(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( this.Data.Stack === undefined ) this.Data.Stack = undefined;
with ( function(){
with ( Data ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Stack module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data';




function Stack ( )
{
  this.length = 0;
}

var proto = Stack.prototype;

proto.pop  = Array.prototype.pop;
proto.push = Array.prototype.push;

proto.peek = function ( )
{
  return this.length > 0
           ?  this[this.length-1]
           :  undefined;
};

proto.isEmpty = function ( )
{
  return this.length == 0;
};

          return {
              Stack: Stack
          };
      }();
  }
}.call(null) ) {
  this.Data.Stack = Stack;
}
}).call(null);
(function(){
with ( function(){

      return function () {
          var VERSION = '0.1.0';
          var NAMESPACE;
          




Function.prototype.bind = function ( o ) {
  var f = this;
  return function ( ) {
      return f.apply(o, arguments);
  };
};

          return {
              
          };
      }();
  }.call(null) ) {
}
}).call(null);
(function(){
  if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
  if ( !this.WebBrowser.GUI || (typeof this.WebBrowser.GUI != 'object' && typeof this.WebBrowser.GUI != 'function') ) this.WebBrowser.GUI = new Object();
  if ( !this.WebBrowser.GUI.Event || (typeof this.WebBrowser.GUI.Event != 'object' && typeof this.WebBrowser.GUI.Event != 'function') ) this.WebBrowser.GUI.Event = new Object();
  if ( this.WebBrowser.GUI.Event.attach === undefined ) this.WebBrowser.GUI.Event.attach = undefined;
  if ( this.WebBrowser.GUI.Event.detach === undefined ) this.WebBrowser.GUI.Event.detach = undefined;
with ( function(){
with ( WebBrowser.GUI.Event ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          


NAMESPACE = 'WebBrowser.GUI.Event';




var listener_id = 0;
var registry = {};

attach(window, "unload", function(){
  for ( var i in registry ) detach(Number(i));
});




function attach ( element, type, listener, useCapture ) {
  if ( !element || typeof element !== "object" ) {
      throw new TypeError("argument not a element: " + element);
  }
  type = String(type);
  if ( typeof listener !== "function" ) {
      throw new TypeError("argument not a function: " + listener);
  }
  useCapture = Boolean(useCapture);
  
  function handler ( e ) {
      e = e || window.event;
      if ( !e.stopPropagation ) { // Sets standard properties for IE
          e.target        = e.srcElement;
          e.currentTarget = this;
          e.cancelable    = true;
          e.stopPropagation = function stopPropagation ( ) {
              this.cancelBubble = true;
          };
          var prevent_default = false;
          e.preventDefault = function preventDefault ( ) {
              prevent_default = true;
          };
      }
      var ret_val = listener.call(this, e);
      return prevent_default ? false : ret_val;
  }
  
  if ( element.addEventListener ) {
      element.addEventListener(type, handler, useCapture);
  } else if ( element.attachEvent ) {
      element.attachEvent("on"+type, handler);
  } else {
      element["on"+type] = handler;
  }
  
  var id = listener_id++;
  registry[id] = {
      element   : element,
      type      : type,
      listener  : listener,
      useCapture: useCapture,
      handler   : handler
  };
  return id;
}



function detach ( element, type, listener, useCapture ) {
  if ( arguments.length === 1 && typeof element === "number" ) {
      if ( !registry[element] ) return false;
      var reg    = registry[element];
      delete registry[element];
      return detach_aux(reg.element, reg.type, reg.handler, reg.useCapture);
  } else {
      if ( !element || typeof element !== "object" ) {
          throw new TypeError("argument is not an element: " + element);
      }
      type = String(type);
      if ( typeof listener !== "function" ) {
          throw new TypeError("argument is not s function: " + listener);
      }
      useCapture = Boolean(useCapture);
      var ret_val = false;
      for ( var i in registry ) {
          var reg = registry[i];
          if ( reg.element    === element
            && reg.type       === type
            && reg.listener   === listener
            && reg.useCapture === useCapture )
          {
              delete registry[i];
              ret_val = detach_aux(reg.element, reg.type, reg.handler, reg.useCapture) || ret_val;
          }
      }
      return ret_val;
  }
};

function detach_aux ( element, type, listener, useCapture ) {
  return  element.removeEventListener  ?  element.removeEventListener(type, listener, useCapture)  :
          element.detachEvent          ?  element.detachEvent("on"+type, listener)                 :
                                          delete element["on"+type]                                ;
}

          return {
              detach: detach, attach: attach
          };
      }();
  }
}.call(null) ) {
  this.WebBrowser.GUI.Event.detach = detach;
  this.WebBrowser.GUI.Event.attach = attach;
}
}).call(null);

(function(){
  this.GLOBAL = this;
}).call(null);
(function(){
  if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
  if ( this.Math.ToInteger === undefined ) this.Math.ToInteger = undefined;
  if ( this.Math.ToInt32 === undefined ) this.Math.ToInt32 = undefined;
  if ( this.Math.ToUInt32 === undefined ) this.Math.ToUInt32 = undefined;
  if ( this.Math.ToUInt16 === undefined ) this.Math.ToUInt16 = undefined;
with ( function(){
with ( Math ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Math.ToInteger module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Math';



// This module provides functions emulating the integral type 
// conversions defined in ECMA-262 3rd.



function ToInteger ( n ) {
  return n < 0 ? ceil(n)
               : floor(n) || 0;
}



function ToInt32 ( n ) {
  return n | 0;
}



function ToUInt32 ( n ) {
  return n >>> 0;
}



function ToUInt16 ( n ) {
  return n & 0xFFFF;
}


          return {
              ToUInt16: ToUInt16, ToUInt32: ToUInt32, ToInt32: ToInt32, ToInteger: ToInteger
          };
      }();
  }
}.call(null) ) {
  this.Math.ToUInt16 = ToUInt16;
  this.Math.ToUInt32 = ToUInt32;
  this.Math.ToInt32 = ToInt32;
  this.Math.ToInteger = ToInteger;
}
}).call(null);
(function(){
  if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
  if ( !this.WebBrowser.ScriptExecuter || (typeof this.WebBrowser.ScriptExecuter != 'object' && typeof this.WebBrowser.ScriptExecuter != 'function') ) this.WebBrowser.ScriptExecuter = new Object();
  if ( this.WebBrowser.ScriptExecuter.register === undefined ) this.WebBrowser.ScriptExecuter.register = undefined;
  if ( this.WebBrowser.ScriptExecuter.exec === undefined ) this.WebBrowser.ScriptExecuter.exec = undefined;
with ( function(){
with ( WebBrowser.ScriptExecuter ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          

NAMESPACE = 'WebBrowser.ScriptExecuter';



var executers    = {};
var default_type = "text/javascript";



function register ( type, exec ) {
  if ( typeof exec != "function" ) throw new TypeError("function required, but got: " + exec);
  executers[String(type).toLowerCase()] = exec;
}



function exec ( ) {
  var metas = document.getElementsByTagName("META");
  for ( var i=0;  i < metas.length;  i++ ) {
      if ( String(metas[i].httpEquiv).match(/^Content-Script-Type$/i) ) {
          default_type = metas[i].content;
      }
  }
  var scripts = document.getElementsByTagName("SCRIPT");
  for ( var i=0;  i < scripts.length;  i++ ) {
      (function( el ){
          setTimeout(function(){ exec_aux(el); }, 0);
      })(scripts[i]);
  }
}


function exec_aux ( el ) {
  var mime = parseMIMEType(el.type ? el.type : default_type);
  if ( executers[mime.type] ) {
      if ( el.src ) {
          var req = createXHR();
          req.open("GET", el.src, true);
          req.onreadystatechange = function ( ) {
              if ( req.readyState == 4 ) rest(req.responseText);
          };
          req.send(null);
      } else {
          rest(el.innerHTML);
      }
  }
  function rest ( source ) {
      el.parentNode.removeChild(el);
      executers[mime.type](source, mime.attr);
  }
}


function createXHR ( ) {
  try {
      return new XMLHttpRequest();
  } catch (_){
      try {
          return new ActiveXObject("Msxml2.XMLHTTP");
      } catch (_){
          return new ActiveXObject("Microsoft.XMLHTTP");
      }
  }
}


var NOT_TSPECIAL  = '[^][()<>@,;:\\\\"/?=\\x00-\\x20]';
var TOKEN         = "(?:" + NOT_TSPECIAL + "+)";
var MIME_TYPE     = "(?:" + TOKEN + "/" + TOKEN + ")";
var QUOTED_STRING = '(?:"[^"]*(?:\\\\.[^"]*)*")';
var VALUE         = "(?:" + TOKEN + "|" + QUOTED_STRING + ")";

function parseMIMEType ( text ) {
  text = String(text);
  var re = new RegExp("^" + MIME_TYPE, "g");
  re.lastIndex = 0;
  var result = re.exec(text);
  if ( !result ) return {type:text.toLowerCase(), attr:{}};
  var type = result[0].toLowerCase();
  var attr = {};
  text = text.substring(re.lastIndex);
  re = new RegExp("^\\s*;\\s*(" + TOKEN + ")\\s*=\\s*(" + VALUE + ")", "g");
  re.lastIndex = 0;
  while ( result = re.exec(text) ) {
      attr[result[1].toLowerCase()] = result[2];
      text = text.substring(re.lastIndex);
      re.lastIndex = 0;
  }
  return {type:type, attr:attr};
}


if ( window.addEventListener ) {
  window.addEventListener("load", exec, false);
} else if ( window.attachEvent ) {
  window.attachEvent("onload", exec);
} else {
  if ( window.onload ) {
      var temp = window.onload;
      window.onload = function ( ) {
          var r = temp.apply(this, arguments);
          exec();
          return r;
      };
  } else {
      window.onload = exec;
  }
}

          return {
              register: register, exec: exec
          };
      }();
  }
}.call(null) ) {
  this.WebBrowser.ScriptExecuter.register = register;
  this.WebBrowser.ScriptExecuter.exec = exec;
}
}).call(null);
(function(){
  if ( !this.JSON || (typeof this.JSON != 'object' && typeof this.JSON != 'function') ) this.JSON = new Object();
  if ( this.JSON.dump === undefined ) this.JSON.dump = undefined;
with ( function(){
with ( JSON ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          

NAMESPACE = 'JSON';




var DUMPER = "JSON.dumper";



function dump ( data, opts ) {
  opts = opts || {};
  var indent = String(opts.indent);
  if ( !indent.match(/^\s*$/) ) indent = "  ";
  return dump_main(data, {pretty:opts.pretty, indent:indent, deflate:opts.deflate});
}


function dump_main ( data, opts ) {
  switch ( typeof data ) {
    case "undefined":
      return opts.deflate ? '(void 0)' : '"undefined"';

    case "boolean":
    case "number":
      return String(data);

    case "string":
      return dump_string(data);

    case "function":
    case "object":
      if ( data === null ) {
          return "null";
      } else if ( typeof data[DUMPER] == "function" ){
          return data[DUMPER](opts);
      } else if ( data instanceof Array ) {
          var arr = [];
          for ( var i=0;  i < data.length;  i++ ) arr[i] = dump_main(data[i], opts);
          if ( opts.pretty ) {
              return "[\n" + arr.join(",\n").replace(/^/mg, opts.indent) + "\n]";
          } else {
              return "[" + arr.join(",") + "]";
          }
      } else {
          var arr = [];
          for ( var i in data ) {
              if ( data.hasOwnProperty(i) ) {
                  arr.push(dump_string(i) + ":" + dump_main(data[i], opts));
              }
          }
          if ( opts.pretty ) {
              return "{\n" + arr.join(",\n").replace(/^/mg, opts.indent) + "\n}";
          } else {
              return "{" + arr.join(",") + "}";
          }
      }
  }
}


function dump_string ( str ) {
  return '"' + str.replace(/[^\u0020-\u0021\u0023-\u005B\u005D-\u007E]/g, function (c){
                           // any ASCII character except '"', '\' and control-character
      c = c.charCodeAt(0);
      switch ( c ) {
        case '"' : return '\\"';
        case '\\': return '\\\\';
        case '\b': return '\\b';
        case '\f': return '\\f';
        case '\n': return '\\n';
        case '\r': return '\\r';
        case '\t': return '\\t';
        default:
          c = c.toString(16);
          while ( c.length < 4 ) c = "0" + c;
          return "\\u" + c;
      }
  }) + '"';
}



String.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? "new String(" + dump_string(this.toString()) + ")"
                      : dump_string(this.toString());
};

Boolean.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? "new Boolean(" + this.toString() + ")"
                      : this.toString();
};

Number.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? "new Number(" + this.toString() + ")"
                      : this.toString();
};

Date.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? "new Date(" + this.valueOf() + ")"
                      : dump_string(this.toString());
};

RegExp.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? this.toString()
                      : dump_string(this.toString());
};

Function.prototype[DUMPER] = function ( opts ) {
  return opts.deflate ? this.toString()
                      : dump_string(this.toString());
};



          return {
              dump: dump
          };
      }();
  }
}.call(null) ) {
  this.JSON.dump = dump;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Data.Cons.Cell === undefined ) this.Data.Cons.Cell = undefined;
  if ( this.Data.Cons.Nil === undefined ) this.Data.Cons.Nil = undefined;
  if ( this.Data.Cons.nil === undefined ) this.Data.Cons.nil = undefined;
  if ( this.Data.Cons.cons === undefined ) this.Data.Cons.cons = undefined;
  if ( this.Data.Cons.car === undefined ) this.Data.Cons.car = undefined;
  if ( this.Data.Cons.cdr === undefined ) this.Data.Cons.cdr = undefined;
with ( function(){
with ( Data.Cons ) {

      return function () {
          var VERSION = '0.2.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Cons code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Cons';





function Cell ( car, cdr ) {
  this.car = car;
  this.cdr = cdr;
}

var proto = Cell.prototype;

proto.toString = function ( ) {
  return "(" + this.car + " . " + this.cdr + ")";
};

proto.toLocaleString = function ( ) {
  return "("
       + (this.car == null ? String(this.car) : this.car.toLocaleString)
       + " . "
       + (this.cdr == null ? String(this.cdr) : this.cdr.toLocaleString)
       + ")";
};

proto.isNil = function ( ) {
  return false;
};




function Nil ( ) {
  this.car = this;
  this.cdr = this;
}

var proto = Nil.prototype = new Cell();
proto.constructor = Nil;

proto.toString       = 
proto.toLocaleString = function ( ) {
  return "nil";
};

proto.isNil = function ( ) {
  return true;
};




function nil ( ) {
  return new Nil();
};



function cons ( car, cdr ) {
  return new Cell(car, cdr);
}



function car ( cell ) {
  return cell.car;
}



function cdr ( cell ) {
  return cell.cdr;
}


          return {
              nil: nil, Nil: Nil, car: car, Cell: Cell, cdr: cdr, cons: cons
          };
      }();
  }
}.call(null) ) {
  this.Data.Cons.nil = nil;
  this.Data.Cons.Nil = Nil;
  this.Data.Cons.car = car;
  this.Data.Cons.Cell = Cell;
  this.Data.Cons.cdr = cdr;
  this.Data.Cons.cons = cons;
}
}).call(null);
(function(){
  if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
  if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
  if ( this.Util.Arrayize.arrayize === undefined ) this.Util.Arrayize.arrayize = undefined;
with ( function(){
with ( Util.Arrayize ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          


NAMESPACE = 'Util.Arrayize';




var slice = Array.prototype.slice;


function arrayize ( o ) {
  if ( !o ) return [];
  try {
      return slice.call(o, 0);
  } catch ( e ) {
      var r = [];
      for ( var i=0;  i < o.length;  i++ ) {
          r[i] = o[i];
      }
      return r;
  }
}


          return {
              arrayize: arrayize
          };
      }();
  }
}.call(null) ) {
  this.Util.Arrayize.arrayize = arrayize;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.Functional.discontinue === undefined ) this.Data.Functional.discontinue = undefined;
  if ( this.Data.Functional.DiscontinueException === undefined ) this.Data.Functional.DiscontinueException = undefined;
  if ( this.Data.Functional.ignore === undefined ) this.Data.Functional.ignore = undefined;
  if ( this.Data.Functional.IgnoreException === undefined ) this.Data.Functional.IgnoreException = undefined;
  if ( this.Data.Functional.return_list === undefined ) this.Data.Functional.return_list = undefined;
  if ( this.Data.Functional.ReturnListException === undefined ) this.Data.Functional.ReturnListException = undefined;
  if ( this.Data.Functional.Loop.EndOfLoopException === undefined ) this.Data.Functional.Loop.EndOfLoopException = undefined;
  if ( this.Data.Functional.Loop.wrap_for_forEach === undefined ) this.Data.Functional.Loop.wrap_for_forEach = undefined;
  if ( this.Data.Functional.Loop.wrap_for_fold === undefined ) this.Data.Functional.Loop.wrap_for_fold = undefined;
  if ( this.Data.Functional.Loop.wrap_for_map === undefined ) this.Data.Functional.Loop.wrap_for_map = undefined;
with ( function(){
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */






NAMESPACE = 'Data.Functional';



function discontinue ( /* variable arguments */ ) {
  throw new DiscontinueException(arguments);
}


function DiscontinueException ( args ) {
  this.args = args;
}
var proto = DiscontinueException.prototype;
proto.name    = NAMESPACE + ".DiscontinueException";
proto.message = "unusual use of `discontinue' (this should be caught by `forEach' or other iteration-methods).";



function ignore ( /* variable arguments */ ) {
  throw new IgnoreException(arguments);
}


function IgnoreException ( args ) {
  this.args = args;
}
var proto = IgnoreException.prototype;
proto.name    = NAMESPACE + ".IgnoreException";
proto.message = "unusual use of `ignore' (this should be caught by `forEach' or other iteration-methods).";



function return_list ( /* variable arguments */ ) {
  throw new ReturnListException(arguments);
}


function ReturnListException ( args ) {
  this.args = args;
}
var proto = ReturnListException.prototype;
proto.name    = NAMESPACE + ".ReturnListException";
proto.message = "unusual use of `return_list' (this should be caught by `forEach' or other iteration-methods).";



NAMESPACE = 'Data.Functional.Loop';



function EndOfLoopException ( v ) {
  this.result = v;
}
var proto = EndOfLoopException.prototype;
proto.name    = NAMESPACE + ".EndOfLoopException";
proto.message = "this should be caught by `forEach' or other iteration-methods";



function wrap_for_forEach ( t, f ) {
  if ( typeof f != "function" ) throw new TypeError("argument to forEach must be function");
  return function ( v ) {
      try {
          f.call(t, v);
      } catch ( e ) {
          if ( e instanceof DiscontinueException ) {
              throw new EndOfLoopException();
          } else if ( e instanceof IgnoreException ) {
              // Do nothing.
          } else if ( e instanceof ReturnListException ) {
              // Do nothing.
          } else {
              throw e;
          }
      }
  };
}



function wrap_for_fold ( t, f, s ) {
  if ( typeof f != "function" ) throw new TypeError("argument to fold must be function");
  return function ( v ) {
      try {
          return s = f.call(t, s, v);
      } catch ( e ) {
          if ( e instanceof DiscontinueException ) {
              throw new EndOfLoopException(e.args[e.args.length-1]);
          } else if ( e instanceof IgnoreException ) {
              return s;
          } else if ( e instanceof ReturnListException ) {
              return s = f.call(t, s, e.args[e.args.length-1]);
          } else {
              throw e;
          }
      }
  };
}



function wrap_for_map ( t, f, a ) {
  if ( typeof f != "function" ) throw new TypeError("argument to map must be function");
  if ( typeof a != "function" ) throw new TypeError("the third argument to wrap_for_map must be function");
  return function ( v ) {
      try {
          a.call(null, f.call(t, v));
      } catch ( e ) {
          if ( e instanceof DiscontinueException ) {
              a.apply(null, e.args);
              throw new EndOfLoopException();
          } else if ( e instanceof IgnoreException ) {
              // Do nothing.
          } else if ( e instanceof ReturnListException ) {
              a.apply(null, e.args);
          } else {
              throw e;
          }
      }
  };
}

          return {
              DiscontinueException: DiscontinueException, wrap_for_forEach: wrap_for_forEach, wrap_for_map: wrap_for_map, ignore: ignore, discontinue: discontinue, ReturnListException: ReturnListException, wrap_for_fold: wrap_for_fold, return_list: return_list, IgnoreException: IgnoreException, EndOfLoopException: EndOfLoopException
          };
      }();
  }
}
}.call(null) ) {
  this.Data.Functional.DiscontinueException = DiscontinueException;
  this.Data.Functional.Loop.wrap_for_forEach = wrap_for_forEach;
  this.Data.Functional.Loop.wrap_for_map = wrap_for_map;
  this.Data.Functional.ignore = ignore;
  this.Data.Functional.discontinue = discontinue;
  this.Data.Functional.ReturnListException = ReturnListException;
  this.Data.Functional.Loop.wrap_for_fold = wrap_for_fold;
  this.Data.Functional.return_list = return_list;
  this.Data.Functional.IgnoreException = IgnoreException;
  this.Data.Functional.Loop.EndOfLoopException = EndOfLoopException;
}
}).call(null);
(function(){
  if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
  if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
with ( function(){
with ( Util.Arrayize ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          









var null_constructor = function (){};

Function.prototype.extend = function extend ( init, props ) {
  if ( typeof init !== "function" ) throw new TypeError("function is expected: " + init);
  if ( props == null ) props = {};
  
  var SuperClass = this;
  var SubClass = function ( ) {
      var self = this;
      var super_is_called = false;
      function super_call ( ) {
          if ( super_is_called ) throw new Error("super-constructor has already been called");
          super_is_called = true;
          var ret_val = SuperClass.apply(self, arguments);
          if ( ret_val instanceof Object ) {
              for ( var i in ret_val ) {
                  if ( ret_val.hasOwnProperty(i) ) self[i] = ret_val[i];
              }
          }
          return ret_val;
      }
      arguments = arrayize(arguments);
      arguments.unshift(super_call);
      return init.apply(self, arguments);
  };
  
  null_constructor.prototype = SuperClass.prototype;
  var proto = SubClass.prototype = new null_constructor;
  proto.constructor = SubClass;
  proto.$super = function ( prop ) {
      if ( !arguments.length ) return SuperClass;
      var value = SuperClass.prototype[prop];
      if ( typeof value === "function" ) {
          return value.bind(this);
      } else {
          return value;
      }
  };
  for ( var i in props ) proto[i] = props[i];
  
  return SubClass;
};


          return {
              
          };
      }();
  }
}.call(null) ) {
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( this.Data.Error.Error === undefined ) this.Data.Error.Error = undefined;
  if ( this.Data.Error.Exception === undefined ) this.Data.Error.Exception = undefined;
with ( function(){
with ( Data.Error ) {

      return function () {
          var VERSION = '0.3.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Error module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Data.Error';








var Error = GLOBAL.Error.extend(
  function ( $super, message ) {
      $super(message);
  },
  {
      name    : NAMESPACE + ".Error",
      message : "something's wrong",
      toString: function ( ) {
          var s = String(this.message);
          s = s  ?  this.name + ": " + s
                 :  this.name;
          if ( this.fileName ) {
              s += " @" + this.fileName + ":" + this.lineNumber;
          }
          return s;
      }
  }
);



var Exception = GLOBAL.Error.extend(
  function ( $super, message ) {
      $super(message);
  },
  {
      name    : NAMESPACE + ".Exception",
      message : "an exception has occurred",
      toString: function ( ) {
          var s = String(this.message);
          s = s  ?  this.name + ": " + s
                 :  this.name;
          if ( this.fileName ) {
              s += " @" + this.fileName + ":" + this.lineNumber;
          }
          return s;
      }
  }
);


          return {
              Error: Error, Exception: Exception
          };
      }();
  }
}.call(null) ) {
  this.Data.Error.Error = Error;
  this.Data.Error.Exception = Exception;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( this.Data.Error.IllegalStateError === undefined ) this.Data.Error.IllegalStateError = undefined;
with ( function(){
with ( Data.Error ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Error.IllegalStateError module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */




NAMESPACE = 'Data.Error';





var IllegalStateError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".IllegalStateError",
      message: "illegal state"
  }
);


          return {
              IllegalStateError: IllegalStateError
          };
      }();
  }
}.call(null) ) {
  this.Data.Error.IllegalStateError = IllegalStateError;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( this.Data.Error.UnimplementedMethodError === undefined ) this.Data.Error.UnimplementedMethodError = undefined;
with ( function(){
with ( Data.Error ) {

      return function () {
          var VERSION = '0.3.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Error.UnimplementedMethodError.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Data.Error';







var UnimplementedMethodError = Error.extend(
  function ( $super, method, invocant, message ) {
      if ( message !== undefined ) {
          $super(message);
      } else {
          $super("an required method `" + method + "' has not been implemented");
      }
      this.method   = method;
      this.invocant = invocant;
  },
  { name: NAMESPACE + ".UnimplementedMethodError" }
);


          return {
              UnimplementedMethodError: UnimplementedMethodError
          };
      }();
  }
}.call(null) ) {
  this.Data.Error.UnimplementedMethodError = UnimplementedMethodError;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( this.Data.Iterator.NoSuchElementError === undefined ) this.Data.Iterator.NoSuchElementError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

      return function () {
          var VERSION = '0.2.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Iterator code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Iterator';








var NoSuchElementError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".NoSuchElementError",
      message: "no such element"
  }
);


          return {
              NoSuchElementError: NoSuchElementError
          };
      }();
  }
}
}.call(null) ) {
  this.Data.Iterator.NoSuchElementError = NoSuchElementError;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.Functional.Enumerable === undefined ) this.Data.Functional.Enumerable = undefined;
  if ( this.Data.Functional.EmptyEnumerationError === undefined ) this.Data.Functional.EmptyEnumerationError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Functional';












function Enumerable ( ) {
  // This is a kind of abstract class.
}

var proto = Enumerable.prototype;

var obj_name = "[object " + NAMESPACE + ".Enumerable]";


proto.toString = function ( ) {
  return obj_name;
};


proto.iterator = function ( ) {
  throw new UnimplementedMethodError("iterator", this);
};


proto.forEach = function ( f ) {
  var ret_val;
  f = wrap_for_forEach(this, f);
  for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
      try {
          f(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return;
          else                                   throw e;
      }
  }
};


proto.fold = function ( f, s ) {
  f = wrap_for_fold(this, f, s);
  for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
      try {
          s = f(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return e.result;
          else                                   throw e;
      }
  }
  return s;
};


proto.fold1 = function ( f ) {
  var it = this.iterator();
  if ( it.isTail() ) throw new EmptyEnumerationError();
  var s = it.value();
  it = it.next();
  f = wrap_for_fold(this, f, s);
  for ( ;  !it.isTail();  it=it.next() ) {
      try {
          s = f(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return e.result;
          else                                   throw e;
      }
  }
  return s;
};


proto.and = function ( ) {
  return this.fold(function ( x, y ) {
      return y || discontinue(y);
  }, true);
};

proto.or = function ( ) {
  return this.fold(function ( x, y ) {
      return y && discontinue(y);
  }, false);
};

proto.all = function ( f ) {
  return this.fold(function ( x, y ) {
      y = f.call(this, y);
      return y || discontinue(y);
  }, true);
};

proto.any = function ( f ) {
  return this.fold(function ( x, y ) {
      y = f.call(this, y);
      return y && discontinue(y);
  }, false);
};




var EmptyEnumerationError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".EmptyEnumerationError",
      message: "empty enumeration"
  }
);


          return {
              EmptyEnumerationError: EmptyEnumerationError, Enumerable: Enumerable
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Functional.EmptyEnumerationError = EmptyEnumerationError;
  this.Data.Functional.Enumerable = Enumerable;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( this.Data.Iterator.Iterator === undefined ) this.Data.Iterator.Iterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

      return function () {
          var VERSION = '0.2.1';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Iterator code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Iterator';








function Iterator ( ) {
  // This is a kind of abstract class.
  // Sub-classes should implement appropreate methods.
}

var proto = Iterator.prototype;

var obj_name = "[object " + NAMESPACE + ".Iterator]";


proto.toString = function ( ) {
  return obj_name;
};


// Returns true if this iterator points to the tail of a list,
// false othersise.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.isTail = function ( ) {
  throw new UnimplementedMethodError("isTail", this);
};


// Returns value of the element which is just after the position 
// this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method, 
// which may throws Data.Iterator.NoSuchElementError.
proto.value = function ( ) {
  throw new UnimplementedMethodError("value", this);
};


// Returns a new iterator that points to the next position to the 
// one which this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method, 
// which may throws Data.Iterator.NoSuchElementError.
proto.next = function ( ) {
  throw new UnimplementedMethodError("next", this);
};


// Returns true if and only if this iterator is associated with the 
// object specified by the argument, false otherwise.
// The default implementation just returns false.
proto.isBoundTo = function ( list ) {
  return false;
};


proto.find = function ( f ) {
  for ( var it=this;  !it.isTail();  it=it.next() ) {
      if ( f(it.value()) ) break;
  }
  return it;
};


          return {
              Iterator: Iterator
          };
      }();
  }
}
}.call(null) ) {
  this.Data.Iterator.Iterator = Iterator;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.Functional.Collection === undefined ) this.Data.Functional.Collection = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Functional';












function Collection ( ) {
  // This is kind of abstract class.
}

var proto = Collection.prototype = new Enumerable();
proto.constructor = Collection;

var obj_name = "[object " + NAMESPACE + ".Collection]";


proto.toString = function ( ) {
  return obj_name;
};


proto.toArray = function ( ) {
  var a = [];
  this.forEach(function( it ){
      a.push(it);
  });
  return a;
};


proto.add = function ( /* variable args */ ) {
  throw new UnimplementedMethodError("add", this);
};


proto.addAll = function ( /* variable arguments */ ) {
  var self    = this;
  var changed = false;
  for ( var i=0;  i < arguments.length;  i++ ) {
      var c = arguments[i];
      if ( c instanceof Collection ) {
          c.forEach(function( it ){
              changed = self.add(it) || changed;
          });
      } else if ( c instanceof Array ) {
          changed = this.add.apply(this, c) || changed;
      } else {
          chagned = this.add(c) || changed;
      }
  }
  return changed;
};


proto.removeAt = function ( it ) {
  throw new UnimplementedMethodError("removeAt", this);
};


proto.isEmpty = function ( ) {
  return this.iterator().isTail();
};


proto.empty = function ( ) {
  var it;
  while ( !(it=this.iterator()).isTail() ) this.removeAt(it);
};


proto.size = function ( ) {
  var i = 0;
  this.forEach(function(){ ++i; });
  return i;
};


proto.emptyCopy = function ( ) {
  return new this.constructor();
};


proto.copy = function ( ) {
  var c = this.emptyCopy();
  this.forEach(function( it ){
      c.add(it);
  });
  return c;
};


proto.map = function ( f ) {
  var c = this.emptyCopy();
  f = wrap_for_map(this, f, function ( ) {
      c.add.apply(c, arguments);
  });
  for ( var it=this.iterator();  !it.isTail();  it=it.next() ) {
      try {
          f(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return c;
          else                                   throw e;
      }
  }
  return c;
};


proto.filter = function ( f ) {
  return this.map(function( it ){
      if ( f.call(this, it) ) return it;
      else                    ignore();
  });
};


proto.grep = function ( re ) {
  if ( !(re instanceof RegExp) ) re = new Regex(re);
  return this.filter(function(it){
      return String(it).match(re);
  });
};



          return {
              Collection: Collection
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Functional.Collection = Collection;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( this.Data.Iterator.BidirectionalIterator === undefined ) this.Data.Iterator.BidirectionalIterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {

      return function () {
          var VERSION = '0.2.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Iterator code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Iterator';










function BidirectionalIterator ( ) {
  // This is a kind of abstract class.
  // Sub-classes should implement appropreate methods.
}

var proto = BidirectionalIterator.prototype = new Iterator();
proto.constructor = BidirectionalIterator;

var obj_name = "[object " + NAMESPACE + ".BidirectionalIterator]";


proto.toString = function ( ) {
  return obj_name;
};


// Returns true if this iterator points to the head of a list,
// false othersise.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.isHead = function ( ) {
  throw new UnimplementedMethodError("isHead", this);
};


// Returns a new iterator that points to the previous position to 
// the one which this iterator points to.
// The default implementation merely throws UnimplementedMethodError.
// Sub-classes must implement their own version of this method.
proto.previous = function ( ) {
  throw new UnimplementedMethodError("previous", this);
};


          return {
              BidirectionalIterator: BidirectionalIterator
          };
      }();
  }
}
}.call(null) ) {
  this.Data.Iterator.BidirectionalIterator = BidirectionalIterator;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.Functional.Set === undefined ) this.Data.Functional.Set = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.4.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Functional';














function Set ( ) {
  // This is kind of interface.
}

var proto = Set.prototype = new Collection();
proto.constructor = Set;

var obj_name = "[object " + NAMESPACE + ".Set]";


proto.toString = function ( ) {
  return obj_name;
};


proto.contains = function ( /* variable args */ ) {
  throw new UnimplementedMethodError("contains", this);
};

proto.containsAll = function ( /* variable args */ ) {
  for ( var i=0;  i < arguments.length;  i++ ) {
      var e = arguments[i];
      if ( e instanceof Array ) {
          if ( !this.contains.apply(this, e) ) return false;
      } else if ( e instanceof Collection ) {
          var self = this;
          if ( !e.all(function(it){ return self.contains(it); }) ) return false;
      } else {
          if ( !this.contains(e) ) return false;
      }
  }
  return true;
};


proto.remove = function ( /* variable args */ ) {
  throw new UnimplementedMethodError("remove", this);
};

proto.removeAll = function ( /* variable args */ ) {
  var changed = false;
  for ( var i=0;  i < arguments.length;  i++ ) {
      var e = arguments[i];
      if ( e instanceof Array ) {
          changed = this.remove.apply(this, e) || changed;
      } else if ( e instanceof Collection ) {
          var self = this;
          e.forEach(function( it ){
              changed = self.remove(it) || changed;
          });
      } else {
          changed = this.remove(e) || changed;
      }
  }
  return changed;
};

proto.removeAt = function ( it ) {
  if ( !(it instanceof Iterator) ) throw new TypeError("the argument is not of type Data.Iterator.Iterator");
  if ( !it.isBoundTo(this)       ) throw new IllegalStateError();
  var v = it.value();
  this.remove(v);
  return v;
};


proto.retainAll = function ( /* variable args */ ) {
  var temp = this.emptyCopy();
  temp.addAll.apply(temp, arguments);
  return this.removeAll( this.filter(function(it){
      return !temp.contains(it);
  }) );
};



          return {
              Set: Set
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Functional.Set = Set;
}
}).call(null);
(function(){
  if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.Functional.List === undefined ) this.Data.Functional.List = undefined;
with ( function(){
with ( Math ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

// This module should not be required directly.
// Require Data.Functional.List instead.



NAMESPACE = 'Data.Functional';












function List ( ) {
  // This is a kind of abstract class.
}

var proto = List.prototype = new Collection();
proto.constructor = List;


// Iterator methods.
// Return an iterator pointing to just before the n'th element
// (the first element is the 0th one). If there are only n elements 
// in this list, return an iterator pointing to the tail.
// If n is negative, it is treated as size+n, where size is the length 
// of this list. Thus, if n is negative, the result of head(n) and 
// the one of tail(-n) should be equivalent.
// These methods can throw RangeError.
proto.head = function ( n ) {
  if ( n < 0 ) return this.tail(-n);
  return nNextFromHead(this.tail(), n);
};

proto.tail = function ( n ) {
  if ( n < 0 ) return this.head(-n);
  return nPreviousFromTail(this.head(), n);
};

proto.reverseHead = function ( n ) {
  if ( n < 0 ) return this.reverseTail(-n);
  return nNextFromHead(this.reverseTail(), n);
};

proto.reverseTail = function ( n ) {
  if ( n < 0 ) return this.reverseHead(-n);
  return nPreviousFromTail(this.reverseHead(), n);
};

function nNextFromHead ( it, n ) {
  var q = [];
  n = ToInteger(n);
  if ( n == 0 ) {  // simple optimization
      while ( !it.isHead() ) it = it.previous();
      return it;
  } else {
      while ( n-- > 0 ) {
          if ( it.isHead() ) throw new RangeError();
          q.push(it);
          it = it.previous();
      }
      while ( !it.isHead() ) {
          q.shift();
          q.push(it);
          it = it.previous();
      }
      q.push(it);
      return q[0];
  }
}

function nPreviousFromTail ( it, n ) {
  var q = [];
  n = ToInteger(n);
  if ( n == 0 ) {  // simple optimization
      while ( !it.isTail() ) it = it.next();
      return it;
  } else {
      while ( n-- > 0 ) {
          if ( it.isTail() ) throw new RangeError();
          q.push(it);
          it = it.next();
      }
      while ( !it.isTail() ) {
          q.shift();
          q.push(it);
          it = it.next();
      }
      q.push(it);
      return q[0];
  }
}


proto.iterator = function ( /* delegate */ ) {
  return this.head.apply(this, arguments);
};

proto.add = function ( /* variable args */ ) {
  if ( arguments.length == 0 ) return false;
  for ( var i=0;  i < arguments.length;  i++ ) {
      this.tail().insert(arguments[i]);
  }
  return true;
};


// Returns the value indexed by the argument.
// If there is no corresponding value in this list, returns undefined.
// The argument can be either number or iterator.
proto.get = function ( it ) {
  if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
      try {
          it = this.head(it);
      } catch ( e ) {
          if ( e instanceof RangeError ) {
              return undefined;
          } else {
              throw e;
          }
      }
  }
  if ( it.isTail() ) return undefined;
  else               return it.value();
};

// Assigns the second argument to the container indexed by the first 
// argument.
// The argument can be either number or iterator.
proto.set = function ( it, v ) {
  if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
      it = this.head(it);
  }
  return it.assign(v);
};

// Inserts a new container at the position indexed by the first 
// argument, and sets the second argument to the container, then, 
// returns the value of the container.
// The argument can be either number or iterator.
// The position which this iterator points to after insertion is 
// implementation-dependent.
proto.insertAt = function ( it, v ) {
  if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
      it = this.head(it);
  }
  return it.insert(v);
};

// Removes the container indexed by the argument, then, returns the 
// value of the container.
// The argument can be either number or iterator.
// The position which this iterator points to after removal is 
// implementation-dependent.
proto.removeAt = function ( it ) {
  if ( !(it instanceof List.Iterator  &&  it.isBoundTo(this)) ) {
      it = this.head(it);
  }
  return it.remove();
};


proto.pop = function ( ) {
  return this.reverseHead().remove();
};

proto.push = function ( /* variable args */ ) {
  this.add.apply(this, arguments);
  return this.size();
};

proto.shift = function ( ) {
  return this.head().remove();
};

proto.unshift = function ( /* variable args */ ) {
  for ( var i=arguments.length-1;  i >= 0;  i-- ) {
      this.head().insert(arguments[i]);
  }
  return this.size();
};


proto.join = function ( /* delegate */ ) {
  var arr = this.toArray();
  return arr.join.apply(arr, arguments);
};

proto.toString = function ( /* delegate */ ) {
  var arr = this.toArray();
  return arr.toString.apply(arr, arguments);
};

proto.toLocaleString = function ( /* delegate */ ) {
  var arr = this.toArray();
  return arr.toLocaleString.apply(arr, arguments);
};


proto.reverse = function ( ) {
  var r = this.emptyCopy();
  for ( var it=this.reverseHead();  !it.isTail();  it=it.next() ) {
      r.add(it.value());
  }
  return r;
};

proto.slice = function ( start, end ) {
  if ( !(    start instanceof List.Iterator
          &&   end instanceof List.Iterator
          && start.isBoundTo(this) && end.isBoundTo(this)
          && start.constructor === end.constructor ) )  // one might be reverse-iterator even though the other is iterator.
  {
      try {
          start = this.head(start);
      } catch ( e ) {
          if ( e instanceof RangeError ) {
              start = start < 0 ? this.head() : this.tail();
          } else {
              throw e;
          }
      }
      if ( end === undefined ) {
          end = this.tail();
      } else {
          try {
              end = this.head(end);
          } catch ( e ) {
              if ( e instanceof RangeError ) {
                  end = end < 0 ? this.head() : this.tail();
              } else {
                  throw e;
              }
          }
      }
  }
  var l = this.emptyCopy();
  if ( start.compareTo(end) >= 0 ) return l;
  while ( !start.equals(end) ) {
      l.add(start.value());
      start = start.next();
  }
  return l;
};

proto.concat = function ( /* variable arguments */ ) {
  var list = this.emptyCopy();
  arguments[-1] = this;
  for ( var i=-1;  i < arguments.length;  i++ ) {
      var e = arguments[i];
      if ( e instanceof List ) {
          e.forEach(function(it){
              list.add(it)
          });
      }
      else if ( e instanceof Array ) {
          for ( var j=0;  j < e.length;  j++ ) list.add(e[j])
      }
      else {
          list.add(e);
      }
  }
  return list;
};


proto.foldl = proto.fold;

proto.foldl1 = proto.fold1;

proto.foldr = function ( f, s ) {
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( var it=this.reverseHead();  !it.isTail();  it=it.next() ) {
      try {
          s = g(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return e.result;
          else                                   throw e;
      }
  }
  return s;
};

proto.foldr1 = function ( f ) {
  var it = this.reverseHead();
  if ( it.isTail() ) throw new EmptyEnumerationError();
  var s = it.value();
  it = it.next();
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( ;  !it.isTail();  it=it.next() ) {
      try {
          s = g(it.value());
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return e.result;
          else                                   throw e;
      }
  }
  return s;
};


          return {
              List: List
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Functional.List = List;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.List || (typeof this.Data.Functional.List != 'object' && typeof this.Data.Functional.List != 'function') ) this.Data.Functional.List = new Object();
  if ( this.Data.Functional.List.Iterator === undefined ) this.Data.Functional.List.Iterator = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.List ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Functional.List';













function Iterator ( ) {
  // This is a kind of abstract class.
}

var proto = Iterator.prototype = new BidirectionalIterator();
proto.constructor = Iterator;

var obj_name = "[object " + NAMESPACE + ".Iterator]";


proto.toString = function ( ) {
  return obj_name;
};


// Assign the argument to the element which is just after the position 
// this iterator points to, then returns the new value of the element, 
// which can be defferent from the argument.
// The effect of assignment at the tail of a list should be identical 
// to the one of insertion.
// The default implementation merely throws UnimplementedMethodError.
proto.assign = function ( v ) {
  throw new UnimplementedMethodError("assign", this);
};


// Inserts a new container at the position which this iterator points 
// to and sets the argument to the container, then, returns the value 
// of the container, which can be defferent from the argument.
// The position which the iterator points to after insertion is 
// implementation-dependent.
// The default implementation merely throws UnimplementedMethodError.
proto.insert = function ( v ) {
  throw new UnimplementedMethodError("insert", this);
};


// Removes the container just after the position which this iterator 
// points, then, returns the value of the container.
// The position which the iterator points to after removal is 
// implementation-dependent.
// The default implementation merely throws UnimplementedMethodError.
proto.remove = function ( ) {
  throw new UnimplementedMethodError("remove", this);
};


// Returns true if both this iterator and the argument points to the same position,
// false otherwise.
// The default implementation is based on `compareTo' method.
proto.equals = function ( that ) {
  return this.compareTo(that) === 0;
};


// Returns the distance of this iterator and the argument,
// or undefined if the iterators seem to point to defferent list.
// A negative return value means the arguments succeeds this iterator
// and its magnitude represents the distance of them. Thus, this can be 
// used as comparison-function.
// The default implementation is based on `next', `equals' and `isTail' method.
proto.distance  = 
proto.compareTo = function ( that ) {
  if ( !(that instanceof Iterator) ) return undefined;
  for ( var i=0, l=this, r=that;  ;  i--, l=l.next() ) {
      if ( l.equals(r) ) return i;
      if ( l.isTail() ) break;
  }
  for ( var i=1, l=that.next(), r=this;  ;  i++, l=l.next() ) {
      if ( l.equals(r) ) return i;
      if ( l.isTail() ) break;
  }
  return undefined;
};



          return {
              Iterator: Iterator
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Functional.List.Iterator = Iterator;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.List || (typeof this.Data.Functional.List != 'object' && typeof this.Data.Functional.List != 'function') ) this.Data.Functional.List = new Object();
  if ( this.Data.Functional.List.ReverseIterator === undefined ) this.Data.Functional.List.ReverseIterator = undefined;
with ( function(){
with ( Data.Functional.List ) {

      return function () {
          var VERSION = '0.4.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Functional.List';





// This module provides convinient wrapper to construct 
// reverse iterator from normal list iterator.



function ReverseIterator ( it ) {
  this._it = it;
}

var proto = ReverseIterator.prototype = new Iterator();
proto.constructor = ReverseIterator;


proto.isBoundTo = function ( that ) {
  return this._it.isBoundTo(that);
};

proto.isTail = function ( ) {
  return this._it.isHead();
};

proto.isHead = function ( ) {
  return this._it.isTail();
};

proto.next = function ( ) {
  return new ReverseIterator(this._it.previous());
};

proto.previous = function ( ) {
  return new ReverseIterator(this._it.next());
};

proto.value = function ( ) {
  return this._it.previous().value();
};

proto.assign = function ( v ) {
  return this._it.previous().assign(v);
};

proto.insert = function ( v ) {
  return this._it.insert(v);
};

proto.remove = function ( ) {
  return this._it.previous().remove();
};

proto.equals = function ( that ) {
  if ( !(that instanceof ReverseIterator) ) return false;
  return this._it.equal(taht._it);
};

proto.compareTo = function ( that ) {
  if ( !(that instanceof ReverseIterator) ) return undefined;
  var c = this._it.compareTo(that._it);
  if ( isNaN(d) ) return c;
  return -c;
};

proto.distance = function ( that ) {
  if ( !(that instanceof ReverseIterator) ) return undefined;
  var d = this._it.distance(that._it);
  if ( isNaN(d) ) return d;
  return -d;
};


          return {
              ReverseIterator: ReverseIterator
          };
      }();
  }
}.call(null) ) {
  this.Data.Functional.List.ReverseIterator = ReverseIterator;
}
}).call(null);
(function(){
with ( function(){

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */




// This is just a alias.
// See "Data.Functional.List.list" for the entity of "Data.Functional.List".



          return {
              
          };
      }();
  }.call(null) ) {
}
}).call(null);
(function(){
  if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Data.Cons.list === undefined ) this.Data.Cons.list = undefined;
  if ( this.Data.Cons.InsertAtHeadError === undefined ) this.Data.Cons.InsertAtHeadError = undefined;
  if ( this.Data.Cons.RemoveHeadError === undefined ) this.Data.Cons.RemoveHeadError = undefined;
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {
with ( Data.Cons ) {

      return function () {
          var VERSION = '0.2.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Cons code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Cons';























var proto = new List();
proto.toString       = Cell.prototype.toString;
proto.toLocaleString = Cell.prototype.toLocaleString;
proto.isNil          = Cell.prototype.isNil;
Cell.prototype = proto;
proto.constructor = Cell;

proto = new Cell();
proto.toString       = Nil.prototype.toString;
proto.toLocaleString = Nil.prototype.toLocaleString;
proto.isNil          = Nil.prototype.isNil;
Nil.prototype = proto;
proto.constructor = Nil;



function list ( /* variable args */ ) {
  var head, cell;
  head = cell = new Cell(null, new Nil());
  for ( var i=0;  i < arguments.length;  i++ ) {
      cell = cell.cdr = new Cell(arguments[i], cell.cdr);
  }
  return head.cdr;
}



proto = Cell.prototype;


proto.iterator = 
proto.head     = function ( n ) {
  n = ToInteger(n);
  if ( n < 0 ) return this.tail(-n);
  try {
      for ( var it=new Iterator(this, this, null);  n > 0;  it=it.next(), n-- );
      return it;
  } catch ( e ) {
      if ( e instanceof NoSuchElementError ) {
          throw new RangeError();
      } else {
          throw e;
      }
  }
};

proto.tail = function ( n ) {
  n = ToInteger(n);
  if ( n < 0 ) return this.head(-n);
  for ( var it=new Iterator(this, this, null);  !it.isTail();  it=it.next() );
  try {
      for ( ;  n > 0;  it=it.previous(), n-- );
      return it;
  } catch ( e ) {
      if ( e instanceof NoSuchElementError ) {
          throw new RangeError();
      } else {
          throw e;
      }
  }
};

proto.reverseHead = function ( n ) {
  return new ReverseIterator(this.tail(n));
};

proto.reverseTail = function ( n ) {
  return new ReverseIterator(this.head(n));
};


proto.get = function ( n ) {
  if ( n instanceof Iterator || n instanceof ReverseIterator ) {
      if ( !n.isBoundTo(this) ) throw new IllegalStateError();
      return n.value();
  }
  n = ToInteger(n);
  if ( n < 0 ) return this.reverse().get(-n-1);
  var c = this;
  while ( n !== 0 ) {
      c = c.cdr;
      if ( c.isNil() ) return undefined;
      n--;
  }
  return c.car;
};

proto.set = function ( n, v ) {
  if ( n instanceof Iterator || n instanceof ReverseIterator ) {
      if ( !n.isBoundTo(this) ) throw new IllegalStateError();
      return n.assign(v);
  }
  return this.head(n).assign(v);
};


proto.add = function ( /* variable args */ ) {
  if ( arguments.length == 0 ) return false;
  if ( this.isNil() ) throw new InsertAtHeadError();
  for ( var c=this;  !c.cdr.isNil();  c=c.cdr );
  for ( var i=0;  i < arguments.length;  i++ ) {
      c = c.cdr = new Cell(arguments[i], new Nil());
  }
  return true;
};

proto.shift = function ( ) {
  throw new RemoveHeadError();
};

proto.unshift = function ( ) {
  throw new InsertAtHeadError();
};

proto.pop = function ( ) {
  if ( this.isNil() ) return undefined;
  if ( this.cdr.isNil() ) throw new RemoveHeadError();
  for ( var c=this.cdr;  !c.cdr.cdr.isNil();  c=c.cdr );
  var r = c.cdr.car;
  c.cdr = c.cdr.cdr;
  return r;
};

proto.push = function ( /* variable args */ ) {
  if ( arguments.length == 0 ) return this.size();
  if ( this.isEmpty() ) throw new InsertAtHeadError();
  for ( var l=1, c=this;  !c.cdr.isNil();  l++, c=c.cdr );
  for ( var i=0;  i < arguments.length;  i++, l++ ) {
      c = c.cdr = new Cell(arguments[i], c.cdr);
  }
  return l;
};


proto.isEmpty = function ( ) {
  return this.isNil();
};

proto.empty = function ( ) {
  if ( this.isEmpty() ) return;
  throw new RemoveHeadError();
};

proto.size = function ( ) {
  for ( var i=0, c=this;  !c.isNil();  i++, c=c.cdr );
  return i;
};

proto.copy = function ( ) {
  if ( this.isNil() ) return new Nil();
  var head, cell;
  head = cell = new Cell(this.car, new Nil());
  for ( var c=this.cdr;  !c.isNil();  c=c.cdr ) {
      cell = cell.cdr = new Cell(c.car, cell.cdr);
  }
  return head;
};

proto.toArray = function ( ) {
  var a = [];
  for ( var c=this;  !c.isNil();  c=c.cdr ) a.push(c.car);
  return a;
};

proto.reverse = function ( ) {
  var r = new Nil();
  for ( var c=this;  !c.isNil();  c=c.cdr ) r = new Cell(c.car, r);
  return r;
};

proto.concat = function ( /* variable args */ ) {
  var head, cell;
  head = cell = new Cell(null, new Nil());
  arguments[-1] = this;
  for ( var i=-1;  i < arguments.length;  i++ ) {
      var c = arguments[i];
      if ( c instanceof List ) {
          c.forEach(function( it ){
              cell = cell.cdr = new Cell(it, cell.cdr);
          });
      } else if ( c instanceof Array ) {
          for ( var j=0;  j < c.length;  j++ ) {
              cell = cell.cdr = new Cell(c[j], cell.cdr);
          }
      } else {
          cell = cell.cdr = new Cell(c, cell.cdr);
      }
  }
  return head.cdr;
};

proto.slice = function ( start, end ) {
  if ( !( (   start instanceof Iterator        && end instanceof Iterator
           || start instanceof ReverseIterator && end instanceof ReverseIterator )
         && start.isBoundTo(this) && end.isBoundTo(this) ) )
  {   try {
          start = this.head(start);
      } catch ( e ) {
          if ( e instanceof RangeError ) {
              start = start < 0 ? this.head() : this.tail();
          } else {
              throw e;
          }
      }
      if ( end === undefined ) {
          end = this.tail();
      } else {
          try {
              end = this.head(end);
          } catch ( e ) {
              if ( e instanceof RangeError ) {
                  end = end < 0 ? this.head() : this.tail();
              } else {
                  throw e;
              }
          }
      }
  }
  if ( start.compareTo(end) >= 0 ) return new Nil();
  var head, cell;
  head = cell = new Cell(null, new Nil());
  while ( !start.equals(end) ) {
      cell = cell.cdr = new Cell(start.value(), cell.cdr);
      start = start.next();
  }
  return head.cdr;
}


proto.forEach = function ( f ) {
  f = wrap_for_forEach(this, f);
  for ( var c=this;  !c.isNil();  c=c.cdr ) {
      try {
          f(c.car);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return;
          } else {
              throw e;
          }
      }
  }
};

proto.fold  =
proto.foldl = function ( f, s ) {
  f = wrap_for_fold(this, f, s);
  for ( var c=this;  !c.isNil();  c=c.cdr ) {
      try {
          s = f(c.car);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
  if ( this.isEmpty() ) throw new EmptyEnumerationError();
  var s = this.car;
  f = wrap_for_fold(this, f, s);
  for ( var c=this.cdr;  !c.isNil();  c=c.cdr ) {
      try {
          s = f(c.car);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.foldr = function ( f, s ) {
  return this.reverse().foldl(function(x,y){return f.call(this,y,x);}, s);
};

proto.foldr1 = function ( f ) {
  return this.reverse().foldl1(function(x,y){return f.call(this,y,x);});
};

proto.map = function ( f ) {
  if ( this.isNil() ) return new Nil();
  var head, cell;
  head = cell = new Cell(null, new Nil());
  f = wrap_for_map(this, f, function(){
      for ( var i=0;  i < arguments.length;  i++ ) {
          cell = cell.cdr = new Cell(arguments[i], cell.cdr);
      }
  });
  for ( var c=this;  !c.isNil();  c=c.cdr ) {
      try {
          f(c.car);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return head.cdr;
          } else {
              throw e;
          }
      }
  }
  return head.cdr;
}



function Iterator ( head, cell, prev ) {
  this._head = head;
  this._cell = cell;
  this._prev = prev;
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

proto.isBoundTo = function ( that ) {
  return this._head === that;
};

proto.isHead = function ( ) {
  return this._head === this._cell;
};

proto.isTail = function ( ) {
  return this._cell.isNil();
};

proto.value = function ( ) {
  return this._cell.car;
};

proto.assign = function ( v ) {
  if ( this.isTail() ) this.insert(v);
  else                 this._cell.car = v;
  return v;
};

proto.insert = function ( v ) {
  if ( this.isHead() ) throw new InsertAtHeadError();
  this._cell = this._prev._cell.cdr = new Cell(v, this._cell.cdr);
  return v;
};

proto.remove = function ( ) {
  if ( this.isHead() ) throw new RemoveHeadError();
  if ( this.isTail() ) throw new IllegalStateError("can't remove at tail");
  var r = this._cell.car;
  this._cell = this._prev._cell.cdr = this._cell.cdr;
  return r;
};

proto.next = function ( ) {
  if ( this.isTail() ) throw new NoSuchElementError("no next element");
  return new Iterator(this._head, this._cell.cdr, this);
};

proto.previous = function ( ) {
  if ( this.isHead() ) throw new NoSuchElementError("no previous element");
  return this._prev;
};

proto.equals = function ( that ) {
  return that instanceof Iterator
      && that.isBoundTo(this._head)
      && this._cell === that._cell;
};

proto.compareTo =
proto.distance  = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._head)) ) return undefined;
  for ( var i=0, l=this._cell, r=that._cell;  !l.isNil();  i++, l=l.cdr ) {
      if ( l === r ) return -i;
  }
  for ( var i=1, l=that._cell.cdr, r=this._cell;  !l.isNil();  i++, l=l.cdr ) {
      if ( l === r ) return i;
  }
  return void 0;
};


function ReverseIterator ( ) {
  return List.ReverseIterator.apply(this, arguments);
}

var proto = ReverseIterator.prototype = new List.ReverseIterator();
proto.constructor = ReverseIterator;




var InsertAtHeadError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".InsertAtHeadError",
      message: "can't insert at head of cons-list"
  }
);


var RemoveHeadError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".RemoveHeadError",
      message: "can't remove head of cons-list"
  }
);


          return {
              InsertAtHeadError: InsertAtHeadError, RemoveHeadError: RemoveHeadError, list: list
          };
      }();
  }
}
}
}
}
}
}.call(null) ) {
  this.Data.Cons.InsertAtHeadError = InsertAtHeadError;
  this.Data.Cons.RemoveHeadError = RemoveHeadError;
  this.Data.Cons.list = list;
}
}).call(null);
(function(){
  if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {

      return function () {
          var VERSION = '0.5.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Functional code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


















var proto = Array.prototype;

for ( var i in List.prototype ) {
  if ( typeof proto[i] != "function" ) proto[i] = List.prototype[i];
}


proto.head = function ( n ) {
  if ( n < 0 ) return this.tail(-n);
  n = ToInteger(n);
  if ( n > this.length ) throw new RangeError();
  return new Iterator(this, n);
};

proto.tail = function ( n ) {
  if ( n < 0 ) return this.head(-n);
  n = ToInteger(n);
  if ( n > this.length ) throw new RangeError();
  return new Iterator(this, this.length-n);
};

proto.iterator = proto.head;

proto.reverseHead = function ( n ) {
  if ( n < 0 ) return this.reverseTail(-n);
  n = ToInteger(n);
  if ( n > this.length ) throw new RangeError();
  return new ReverseIterator(this, n);
};

proto.reverseTail = function ( n ) {
  if ( n < 0 ) return this.reverseHead(-n);
  n = ToInteger(n);
  if ( n > this.length ) throw new RangeError();
  return new ReverseIterator(this, this.length-n);
};


proto.add = function ( /* variable args */ ) {
  this.push.apply(this, arguments);
  return true;
};

proto.get = function ( it ) {
  if ( it instanceof Iterator || it instanceof ReverseIterator ) {
      if ( it.isBoundTo(this) ) return it.value();
      throw new IllegalStateError();
  }
  it = ToInteger(n);
  if ( it < 0 ) it += this.length;
  return this[it];
};

proto.set = function ( it, v ) {
  if ( it instanceof Iterator || it instanceof ReverseIterator ) {
      if ( it.isBoundTo(this) ) return it.assign(v);
      throw new IllegalStateError();
  }
  var n = ToInteger(it);
  if ( n < 0            ) n += this.length;
  if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
  if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
  return this[n] = v;
};

proto.insertAt = function ( it, v ) {
  if ( it instanceof Iterator || it instanceof ReverseIterator ) {
      if ( it.isBoundTo(this) ) return it.insert(v);
      throw new IllegalStateError();
  }
  var n = ToInteger(it);
  if ( n < 0            ) n += this.length;
  if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
  if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
  this.splice(n, 0, v);
  return v;
};

proto.removeAt = function ( it ) {
  if ( it instanceof Iterator || it instanceof ReverseIterator ) {
      if ( it.isBoundTo(this) ) return it.remove();
      throw new IllegalStateError();
  }
  var n = ToInteger(it);
  if ( n < 0            ) n += this.length;
  if ( n < 0            ) throw new RangeError("`" + it + "' is too small.");
  if ( n >= this.length ) throw new RangeError("`" + it + "' is too large.");
  return this.splice(n, 1)[0];
};


proto.isEmpty = function ( ) {
  return this.length == 0;
};

proto.empty = function ( ) {
  this.length = 0;
};

proto.size = function ( ) {
  return this.length;
};

proto.copy    =
proto.toArray = function ( ) {
  var a = [];
  for ( var i=0;  i < this.length;  i++ ) a[i] = this[i];
  return a;
};


proto.forEach = function ( f ) {
  f = wrap_for_forEach(this, f);
  for ( var i=0;  i < this.length;  i++ ) {
      try {
          f(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return;
          } else {
              throw e;
          }
      }
  }
};

proto.fold  =
proto.foldl = function ( f, s ) {
  f = wrap_for_fold(this, f, s);
  for ( var i=0;  i < this.length;  i++ ) {
      try {
          s = f(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
  if ( this.length == 0 ) throw new EmptyEnumerationError();
  var s = this[0];
  f = wrap_for_fold(this, f, s);
  for ( var i=1;  i < this.length;  i++ ) {
      try {
          s = f(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.foldr = function ( f, s ) {
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( var i=this.length-1;  i >= 0;  i-- ) {
      try {
          s = f(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.foldr1 = function ( f ) {
  if ( this.length == 0 ) throw new EmptyEnumerationError();
  var s = this[this.length-1];
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( var i=this.length-2;  i >= 0;  i-- ) {
      try {
          s = g(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.map = function ( f ) {
  var a = [];
  f = wrap_for_map(this, f, function(){
      a.push.apply(a, arguments);
  });
  for ( var i=0;  i < this.length;  i++ ) {
      try {
          f(this[i]);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return a;
          else                                   throw e;
      }
  }
  return a;
};


// Re-define concat and slice
var original_concat = proto.concat;
proto.concat = function ( /* variable argumentes */ ) {
  for ( var i=0;  i < arguments.length;  i++ ) {
      var v = arguments[i];
      if ( v instanceof List ) arguments[i] = v.toArray();
  }
  return original_concat.apply(this, arguments);
};

var original_slice = proto.slice;
proto.slice = function ( start, end ) {
  if (   (   start instanceof Iterator        && end instanceof Iterator
          || start instanceof ReverseIterator && end instanceof ReverseIterator )
      && start.isBoundTo(this) && end.isBoundTo(this)  )
  {
      if ( start.compareTo(end) >= 0 ) return [];
      var s = [];
      do {
          s.push(start.value());
          start = start.next();
      } while ( !start.equals(end) );
      return s;
  } else {
      return original_slice.apply(this, arguments);
  }
};



function Iterator ( a, n ) {
  this._arr = a;
  this._pos = n;
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

proto.isBoundTo = function ( that ) {
  return this._arr === that;
};

proto.isHead = function ( ) {
  return ToInteger(this._pos) <= 0
      || this._arr.length == 0;
};

proto.isTail = function ( ) {
  return ToInteger(this._pos) >= this._arr.length
      || this._arr.length == 0;
};

proto.value = function ( ) {
  if ( this.isTail() ) return undefined;
  if ( this.isHead() ) return this._arr[0];
  else                 return this._arr[ToInteger(this._pos)];
};

proto.assign = function ( v ) {
  if ( this.isTail() ) return this.insert();
  if ( this.isHead() ) return this._arr[0] = v;
  else                 return this._arr[ToInteger(this._pos)] = v;
};

proto.insert = function ( v ) {
  var i = ToInteger(this._pos);
  if ( i <= 0 ) i = 0;
  else          i = min(i, this._arr.length);
  return this._arr.insertAt(i, v);
};

proto.remove = function ( ) {
  if      ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
  else if ( this.isHead() ) return this._arr.aplice(0, 1)[0];
  else                      return this._arr.splice(this._pos, 1)[0];
};

proto.next = function ( ) {
  if ( this.isTail() ) throw new NoSuchElement("no next element");
  if ( this.isHead() ) return new this.constructor(this._arr, 1);
  else                 return new this.constructor(this._arr, this._pos+1);
};

proto.previous = function ( ) {
  if ( this.isHead() ) throw new NoSuchElement("no previous element");
  if ( this.isTail() ) return new this.constructor(this._arr, this._arr.length-1);
  else                 return new this.constructor(this._arr, this._pos-1);
};

proto.compareTo = 
proto.distance  = function ( that ) {
  if ( !(that instanceof this.constructor) ) return undefined;
  if ( this._arr !== that._arr             ) return undefined;
  var s = this._arr.length;
  var l = ToInteger(this._pos);
  var r = ToInteger(that._pos);
  if ( l <= 0  &&  r <= 0
    || l >= s  &&  r >= s ) return 0;
  return l - r;
};


function ReverseIterator ( a, n ) {
  Iterator.apply(this, arguments);
}

var proto = ReverseIterator.prototype = new List.Iterator();

for ( var i in Iterator.prototype ) {
  if ( Iterator.prototype.hasOwnProperty(i)
    && typeof Iterator.prototype[i] == "function" )
  {
      proto[i] = Iterator.prototype[i];
  }
}

proto.constructor = ReverseIterator;

proto.value = function ( ) {
  if ( this.isTail() ) return undefined;
  if ( this.isHead() ) return this._arr[this._arr.length-1];
  else                 return this._arr[this._arr.length-1-ToInteger(this._pos)];
};

proto.assign = function ( v ) {
  if ( this.isTail() ) this.insert(v);
  if ( this.isHead() ) return this._arr[this._arr.length-1] = v;
  else                 return this._arr[this._arr.length-1-ToInteger(this._pos)] = v;
};

proto.insert = function ( v ) {
  var i = ToInteger(this._pos);
  if ( i <= 0 ) i = 0;
  else          i = min(i, this._arr.length);
  return this._arr.insertAt(this._arr.length-i, v);
};

proto.remove = function ( ) {
  if ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
  if ( this.isHead() ) return this._arr.splice(this._arr.length-1, 1)[0];
  else                 return this._arr.splice(this._arr.length-1-ToInteger(this._pos), 1)[0];
};


          return {
              
          };
      }();
  }
}
}
}
}.call(null) ) {
}
}).call(null);
(function(){
  if ( !this.Math || (typeof this.Math != 'object' && typeof this.Math != 'function') ) this.Math = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data.Functional.Loop || (typeof this.Data.Functional.Loop != 'object' && typeof this.Data.Functional.Loop != 'function') ) this.Data.Functional.Loop = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Data.LinkedList === undefined ) this.Data.LinkedList = undefined;
with ( function(){
with ( Math ) {
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional.Loop ) {
with ( Data.Functional ) {
with ( Data ) {

      return function () {
          var VERSION = '0.3.1';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.LinkedList module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2005-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data';




















function LinkedList ( /* variable arguments */ ) {
  this._value   = undefined;
  this._prev    = this;
  this._next    = this;
  this._removed = false;
  this.add.apply(this, arguments);
}

LinkedList.fromCollection = function ( /* variable args */ ) {
  var l = new LinkedList();
  l.addAll.apply(l, arguments);
  return l;
};


function makeContainer ( v ) {
  return { _value: v, _removed: false };
}


var proto = LinkedList.prototype = new List();
proto.constructor = LinkedList;


function nForward ( top, c, n ) {
  if ( n == 0 ) return c;
  c = c._next;
  while ( --n > 0 ) {
      if ( c === top ) throw new RangeError();
      c = c._next;
  }
  return c;
}

function nBackward ( top, c, n ) {
  if ( n == 0 ) return c;
  c = c._prev;
  while ( --n > 0 ) {
      if ( c === top ) throw new RangeError();
      c = c._prev;
  }
  return c;
}


proto.head = function ( n ) {
  if ( n < 0 ) return this.tail(-n);
  return new Iterator( this, nForward(this, this._next, ToInteger(n)) );
};

proto.tail = function ( n ) {
  if ( n < 0 ) return this.head(-n);
  return new Iterator( this, nBackward(this, this, ToInteger(n)) );
};

proto.reverseHead = function ( n ) {
  if ( n < 0 ) return this.reverseTail(-n);
  return new ReverseIterator( this, nBackward(this, this._prev, ToInteger(n)) );
};

proto.reverseTail = function ( n ) {
  if ( n < 0 ) return this.reverseHead(-n);
  return new ReverseIterator( this, nBackward(this, this, ToInteger(n)) );
};

proto.iterator = proto.head;


proto.add = function ( /* variable args */ ) {
  if ( !arguments.length ) return false;
  var it = new Iterator(this, this);
  for ( var i=0;  i < arguments.length;  i++ ) it.insert(arguments[i]);
  return true;
};

proto.pop = function ( ) {
  return (new Iterator(this, this._prev)).remove();
};

proto.shift = function ( ) {
  return (new Iterator(this, this._next)).remove();
};

proto.unshift = function ( /* variable arguments */ ) {
  var it = new Iterator(this, this._next);
  for ( var i=0;  i < arguments.length;  i++ ) it.insert(arguments[i]);
  return this.size();
};


proto.isEmpty = function ( ) {
  return this._next === this;
};

proto.empty = function ( ) {
  this._prev = this._next = this;
};

proto.size = function ( ) {
  for ( var i=0, c=this._next;  c !== this;  ++i, c=c._next );
  return i;
};

proto.copy = function ( ) {
  var l = this.emptyCopy();
  for ( var c=this._next;  c !== this;  c=c._next ) l.add(c._value);
  return l;
};

proto.toArray = function ( ) {
  var a = [];
  for ( var c=this._next;  c !== this;  c=c._next ) a.push(c._value);
  return a;
};


proto.forEach = function ( f ) {
  f = wrap_for_forEach(this, f);
  for ( var c=this._next;  c !== this;  c=c._next ) {
      try {
          f(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return;
          } else {
              throw e;
          }
      }
  }
}

proto.fold  =
proto.foldl = function ( f, s ) {
  f = wrap_for_fold(this, f, s);
  for ( var c=this._next;  c !== this;  c=c._next ) {
      try {
          s = f(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.fold1  =
proto.foldl1 = function ( f ) {
  if ( this.isEmpty() ) throw new EmptyEnumerationError();
  var s = this._next._value;
  f = wrap_for_fold(this, f, s);
  for ( var c=this._next._next;  c !== this;  c=c._next ) {
      try {
          s = f(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.foldr = function ( f, s ) {
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( var c=this._prev;  c !== this;  c=c._prev ) {
      try {
          s = f(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.foldr1 = function ( f ) {
  if ( this.isEmpty() ) throw new EmptyEnumerationError();
  var s = this._prev._value;
  var g = wrap_for_fold(this, function(x,y){return f.call(this,y,x);}, s);
  for ( var c=this._prev._prev;  c !== this;  c=c._prev ) {
      try {
          s = g(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) {
              return e.result;
          } else {
              throw e;
          }
      }
  }
  return s;
};

proto.map = function ( f ) {
  var l = new LinkedList();
  f = wrap_for_map(this, f, function(){
      l.add.apply(l, arguments);
  });
  for ( var c=this._next;  c !== this;  c=c._next ) {
      try {
          f(c._value);
      } catch ( e ) {
          if ( e instanceof EndOfLoopException ) return l;
          else                                   throw e;
      }
  }
  return l;
};



// comparison function about containers
function comp ( top, l, r ) {
  if ( l === r ) return 0;
  do {
      l = l._next;
      if ( l === r ) return -1;
  } while ( l !== top );
  return 1;
}

// distance function about containers
function dist ( top, l, r ) {
  for ( var i=0, it=l;  it !== top;  i--, it=it._next ) {
      if ( it === r ) return i;
  }
  for ( var i=1, it=r._next;  it !== top;  i++, it=it._next ) {
      if ( it === l ) return i;
  }
  return undefined;
}


function Iterator ( l, c ) {
  this._top = l;  // LinkedList object which this iterator belongs to.
  this._pos = c;  // Current position; abstractly iterator points to just before this container
}

var proto = Iterator.prototype = new List.Iterator();
proto.constructor = Iterator;

function validate ( it ) {
  while ( it._pos._removed ) {
      it._pos = it._pos._next;
  }
}

proto.isBoundTo = function ( that ) {
  return this._top === that;
};

proto.equals = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return false;
  validate(this);
  validate(that);
  return  this._pos === that._pos;
};

proto.compareTo = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
  validate(this);
  validate(that);
  return comp(this._top, this._pos, that._pos);
};

proto.distance = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
  validate(this);
  validate(that);
  return dist(this._top, this._pos, that._pos);
};

proto.isHead = function ( ) {
  validate(this);
  return this._pos === this._top._next;
};

proto.isTail = function ( ) {
  validate(this);
  return this._pos === this._top;
};

proto.next = function ( ) {
  if ( this.isTail() ) throw new NoSuchElementError("no next element");
  return new Iterator(this._top, this._pos._next);
};

proto.previous = function ( ) {
  if ( this.isHead() ) throw new NoSuchElementError("no previous element");
  return new Iterator(this._top, this._pos._prev);
};

proto.value = function ( ) {
  validate(this);
  return this._pos._value;
};

proto.assign = function ( v ) {
  if ( this.isTail() ) return this.insert(v);
  else                 return this._pos._value = v;
};

proto.insert = function ( v ) {
  validate(this);
  var c = makeContainer(v);
  c._prev = this._pos._prev;
  c._next = this._pos;
  this._pos._prev = this._pos._prev._next = c;
  return v;
};

proto.remove = function ( ) {
  if ( this.isTail() ) throw new IllegalStateError("can't remove at the tail of list");
  this._pos._prev._next = this._pos._next;
  this._pos._next._prev = this._pos._prev;
  this._pos._removed = true;
  return this._pos._value;
};



function ReverseIterator ( l, c ) {
  this._top = l;  // LinkedList object which this iterator belongs to.
  this._pos = c;  // Current position; abstractly iterator points to just before this container
}

var proto = ReverseIterator.prototype = new List.Iterator();
for ( var i in Iterator.prototype ) proto[i] = Iterator.prototype[i];
proto.constructor = ReverseIterator;

function rvalidate ( it ) {
  while ( it._pos._removed ) {
      it._pos = it._pos._prev;
  }
}

proto.isBoundTo = Iterator.prototype.isBoundTo;

proto.equals = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return false;
  rvalidate(this);
  rvalidate(that);
  return  this._pos === that._pos;
};

proto.compareTo = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
  rvalidate(this);
  rvalidate(that);
  return -comp(this._top, this._pos, that._pos);
};

proto.distance = function ( that ) {
  if ( !(that instanceof Iterator && that.isBoundTo(this._top)) ) return undefined;
  rvalidate(this);
  rvalidate(that);
  var d = dist(this._top, this._pos, that._pos);
  return isNaN(d) ? d : -d;
};

proto.isHead = function ( ) {
  rvalidate(this);
  return this._pos === this._top._prev;
};

proto.isTail = function ( ) {
  rvalidate(this);
  return this._pos === this._top;
};

proto.next = function ( ) {
  if ( this.isTail() ) throw new NoSuchElementError("no next element");
  return new ReverseIterator(this._top, this._pos._prev);
};

proto.previous = function ( ) {
  if ( this.isHead() ) throw new NoSuchElementError("no previous element");
  return new ReverseIterator(this._top, this._pos._next);
};

proto.value = function ( ) {
  rvalidate(this);
  return this._pos._value;
};

proto.assign = Iterator.prototype.assign;

proto.insert = function ( v ) {
  rvalidate(this);
  var c = makeContainer(v);
  c._next = this._pos._next;
  c._prev = this._pos;
  this._pos._next = this._pos._next._prev = c;
  return v;
};

proto.remove = Iterator.prototype.remove;


          return {
              LinkedList: LinkedList
          };
      }();
  }
}
}
}
}
}
}.call(null) ) {
  this.Data.LinkedList = LinkedList;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( this.Concurrent.Thread === undefined ) this.Concurrent.Thread = undefined;
with ( function(){
with ( Data.Error ) {
with ( Concurrent ) {

      return function () {
          var VERSION = '0.1.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent';








var current_thread = null;  // Retains the current thread.


function NoContinuationException ( r ) {
  this.ret_val = r;
}

function initial_continuation_procedure ( ret_val ) {
  throw new NoContinuationException(ret_val);
}

function NoExceptionHandlerException ( e ) {
  this.thrown = e;
}

function initial_exception_handler ( e ) {
  throw new NoExceptionHandlerException(e);
}

var initial_continuation = {
  this_val : null,
  procedure: initial_continuation_procedure,
  exception: {
      this_val : null,
      procedure: initial_exception_handler
  }
};
// Cyclic reference ensures that at least one exceptinal continuation always exists.
initial_continuation.exception.exception = initial_continuation.exception;




function Thread ( ) {
  throw new Error("Thread cannot be instantiated directly.");
}

function THREAD ( t ) {
  this._triplet      = t;  // {continuation:{...}, timeout:int|undefined, ret_val:any}
  this._is_ended     = 0;  // 0:running, -1:throw, 1:return
  this._join_thread  = null;
  this._joined_list  = new Data.LinkedList();
  this._timerID      = undefined;
  standBy.call(this, 0);
}

var proto = THREAD.prototype = Thread.prototype;

+function(){
  var name = "[object " + NAMESPACE + ".Thread]"
  proto.toString = function ( ) {
      return name;
  };
}();


// Cancel timeout event.
function cancel ( ) {
  if ( this._timerID ) {
      clearTimeout(this._timerID);
      this._timerID = undefined;
  }
}

// Reserve execution of the next step after t msec.
function standBy ( t ) {
  cancel.call(this);
  var self = this;
  this._timerID = setTimeout(
      function(){ doNext.call(self); },
      Number(t) || 2  // some version of IE occationally fails to 
                      // context-switch with timeout interval less than 2.
  );
}

// Cut "join" link.
function unjoin ( ) {
  if ( this._join_thread ) {
      var self = this;
      var it = this._join_thread._joined_list.head().find(function( it ){
          return it === self;
      });
      it.remove();
      this._join_thread = null;
  }
}


Thread.TIME_SLICE = 20;

function doNext ( ) {
  cancel.call(this);
  var triplet = this._triplet;
  this._triplet = null;
  try {
      current_thread = this;
      var limit = (new Date).valueOf() + Thread.TIME_SLICE;
      do {
          try {
              triplet = triplet.continuation.procedure.call(
                            triplet.continuation.this_val, triplet.ret_val
                       );
          } catch ( e ) {
              if ( e instanceof NoContinuationException ) {
                  this._is_ended = 1;
                  this._result   = e.ret_val;
                  while ( !this._joined_list.isEmpty() ) {
                      var it = this._joined_list.head().value();
                      unjoin.call(it);
                      it._triplet.ret_val = e.ret_val;
                      standBy.call(it);
                  }
                  this._joined_list = null;
                  return;
              } else if ( e instanceof NoExceptionHandlerException ) {
                  e = e.thrown;
                  var joined_list   = this._joined_list;
                  this._joined_list = null;
                  this._is_ended    = -1;
                  this._result      = e;
                  if ( !joined_list.isEmpty() ) {
                      while ( !joined_list.isEmpty() ) {
                          joined_list.head().value().notify(e);  // "notify" implies "unjoin".
                      }
                  } else if ( !(e instanceof KillException) ) {
                      throw e;
                  }
                  return;
              } else {
                  triplet.continuation = triplet.continuation.exception;
                  triplet.ret_val      = e;
              }
          }
      } while ( triplet.timeout === undefined && (new Date).valueOf() < limit );
  } finally {
      current_thread = null;
  }
  this._triplet = triplet;
  if ( triplet.timeout < 0 ) { /* Do nothing. */                   }
  else                       { standBy.call(this, triplet.timeout); }
}


proto.notify = function ( e ) {
  if ( current_thread === this ) throw e;
  if ( this._is_ended ) throw new NotAliveError();
  cancel.call(this);
  unjoin.call(this);
  this._triplet.continuation = this._triplet.continuation.exception;
  this._triplet.ret_val = e;
  standBy.call(this);
  return e;
};

proto.kill = function ( s ) {
  return this.notify( arguments.length ? new KillException(s) : new KillException() );
};

proto.join = function ( ) {
  throw new Error("can't `join' in non-compiled functions");
};

proto.join.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  //!TODO: check cyclic-join
  if ( this_val._is_ended > 0 ) {  // this thread has already ended normally
      return { continuation:cont, ret_val:this_val._result, timeout:undefined };
  } else if ( this_val._is_ended < 0 ) {  // this thread has already ended by exception
      throw this_val._result;
  } else {
      this_val._joined_list.add(current_thread);
      current_thread._join_thread = this_val;
      return { continuation:cont, timeout:-1 };
  }
};



Thread.create = function ( f /* , ... */ ) {
  if ( typeof f != "function" ) throw new TypeError("can't create new thread from non-function value");
  if ( typeof f.$Concurrent_Thread_compiled !== "function" ) f = this.compile(f);
  return f.async(null, Array.prototype.slice.call(arguments, 1, arguments.length));
};


Thread.self = function ( ) {
  return current_thread;
};


Thread.sleep = function ( ) {
  throw new Error("can't `sleep' in non-compiled functions");
};

Thread.sleep.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  return { continuation: cont,
           ret_val     : undefined,
           timeout     : args[0] > 0 ? args[0] : 0 };
};


Thread.stop = function ( ) {
  throw new Error("can't `stop' in non-compiled functions");
};

Thread.stop.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  return { continuation: cont,
           ret_val     : undefined,
           timeout     : -1        };
};


Thread.yield = function ( ) {
  throw new Error("can't `yield' in non-compiled functions");
};

Thread.yield.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  return { continuation: cont,
           ret_val     : undefined,
           timeout     : 0         };
};


var KillException = Thread.KillException = Exception.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".Thread.KillException",
      message: "thread killed"
  }
);

var NotAliveError = Thread.NotAliveError = Error.extend(
  function ( $super, message ) { $super(message); },
  {
      name   : NAMESPACE + ".Thread.NotAliveError",
      message: "thread not alive"
  }
);



// Extends Function object.
var proto = Function.prototype;

proto.apply.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  if ( typeof this_val.$Concurrent_Thread_compiled == "function" ) {
      return this_val.$Concurrent_Thread_compiled(args[0], args[1], cont);
  } else {
      return { continuation: cont,
               ret_val     : this_val.apply(args[0], args[1]) };
  }
};

proto.call.$Concurrent_Thread_compiled = function ( this_val, args, cont ) {
  if ( typeof this_val.$Concurrent_Thread_compiled == "function" ) {
      return this_val.$Concurrent_Thread_compiled(args[0], Array.prototype.slice.call(args, 1, args.length), cont);
  } else {
      return { continuation: cont,
               ret_val     : this_val.apply(args[0], Array.prototype.slice.call(args, 1, args.length)) };
  }
};

proto.async = function ( this_val, args ) {
  if ( typeof this.$Concurrent_Thread_compiled != "function" ) throw new Error("this is not a compiled function");
  if ( args === void 0 ) args = [];  // IE6 does not allow null or undefined-value as the second argument of Function.prototype.apply. That does not conform to ECMA262-3!
  return new THREAD(
      this.$Concurrent_Thread_compiled(
          this_val,
          args,
          initial_continuation
      )
  );
};


          return {
              Thread: Thread
          };
      }();
  }
}
}.call(null) ) {
  this.Concurrent.Thread = Thread;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Data.Cons.Util.last === undefined ) this.Data.Cons.Util.last = undefined;
  if ( this.Data.Cons.Util.adder === undefined ) this.Data.Cons.Util.adder = undefined;
  if ( this.Data.Cons.Util.concat === undefined ) this.Data.Cons.Util.concat = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Cons ) {
with ( Data.Cons.Util ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Data.Cons code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Data.Cons.Util';











function last ( c ) {
  if ( !(c instanceof Cell) ) throw new TypeError("argument is not cons-list");
  if ( c.isNil() ) return c;
  if ( !(c.cdr instanceof Cell) ) throw new TypeError("argument is not cons-list");
  while ( !c.cdr.isNil() ) {
      c = c.cdr;
      if ( !(c.cdr instanceof Cell) ) throw new TypeError("argument is not cons-list");
  }
  return c;
}



function adder ( c ) {
  c = last(c);
  if ( c.isNil() ) throw new IllegalStateError("can't append to nil");
  return function ( /* variable arguments */ ) {
      c = last(c);
      for ( var i=0;  i < arguments.length;  i++ ) {
          c = c.cdr = new Cell(arguments[i], c.cdr);
      }
  };
}



function concat ( /* variable arguments */ ) {
  if ( arguments.length == 0 ) return nil();
  var head = arguments[0];
  var cell = last(head);
  for ( var i=1;  i < arguments.length;  i++ ) {
      cell.cdr = arguments[i];
      cell = last(cell);
  }
  return head;
}


          return {
              adder: adder, concat: concat, last: last
          };
      }();
  }
}
}
}.call(null) ) {
  this.Data.Cons.Util.adder = adder;
  this.Data.Cons.Util.concat = concat;
  this.Data.Cons.Util.last = last;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Concurrent.Thread.Compiler.Kit || (typeof this.Concurrent.Thread.Compiler.Kit != 'object' && typeof this.Concurrent.Thread.Compiler.Kit != 'function') ) this.Concurrent.Thread.Compiler.Kit = new Object();
  if ( this.Concurrent.Thread.Compiler.Kit.printTrees === undefined ) this.Concurrent.Thread.Compiler.Kit.printTrees = undefined;
  if ( this.Concurrent.Thread.Compiler.Kit.codeBug === undefined ) this.Concurrent.Thread.Compiler.Kit.codeBug = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler.Kit ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Igor Bukanov, igor@fastmail.fm
*   Daisuke Maki
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

/**
* This file is based on the file Kit.java in Rhino 1.6R5.
*/




NAMESPACE = 'Concurrent.Thread.Compiler.Kit';








var printTrees = false;  // debug flag



function codeBug ( /* variable arguments */ ) {
  var str = "";
  for ( var i=0;  i < arguments.length;  i++ ) str += arguments[i];
  var e = new Data.Error.IllegalStateError("FAILED ASSERTION: " + str);
  var s = e.toString();
  if ( e.stack ) s += "\n----------\n" + e.stack;
  alert(s);
  throw e;
}


          return {
              printTrees: printTrees, codeBug: codeBug
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.Kit.printTrees = printTrees;
  this.Concurrent.Thread.Compiler.Kit.codeBug = codeBug;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Iterator || (typeof this.Data.Iterator != 'object' && typeof this.Data.Iterator != 'function') ) this.Data.Iterator = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( this.Concurrent.Thread.Compiler.IdentifierSet === undefined ) this.Concurrent.Thread.Compiler.IdentifierSet = undefined;
with ( function(){
with ( Data.Error ) {
with ( Data.Iterator ) {
with ( Data.Functional ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';













var MIN_INT = Math.pow(-2, 53);


function IdentifierSet ( ) {
  this._set      = {};
  this._state_no = MIN_INT;
}

var proto = IdentifierSet.prototype = new Set();
proto.constructor = IdentifierSet;


var hasOwnProperty = Object.prototype.hasOwnProperty;

proto.contains = function ( /* variable arguments */ ) {
  for ( var i=0;  i < arguments.length;  i++ ) {
      var id = arguments[i];
      if ( !(id instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
      // Because "hasOwnProperty" itself can be used as identifier,
      // we need to avoid "this._set.hasOwnProperty".
      if ( !hasOwnProperty.call(this._set, id.valueOf()) ) return false;
  }
  return true;
};


proto.add = function ( /* variable arguments */ ) {
  var changed = false;
  for ( var i=0;  i < arguments.length;  i++ ) {
      var id = arguments[i];
      if ( !(id instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
      var p = id.valueOf();
      if ( this._set[p] !== id ) {
          this._set[p] = id;
          this._state_no++;
          changed = true;
      }
  }
  return changed;
};


proto.remove = function ( /* variable arguments */ ) {
  var changed = false;
  for ( var i=0;  i < arguments.length;  i++ ) {
      var id = arguments[i];
      if ( !(id instanceof Identifier) ) throw new TypeError("argument is not of type Identifier");
      var p = id.valueOf();
      if ( hasOwnProperty.call(this._set, p) ) {
          delete this._set[p];
          this._state_no++;
          changed = true;
      }
  }
  return changed;
};


proto.toArray = function ( ) {
  var arr = [];
  for ( var i in this._set ) {
      if ( hasOwnProperty.call(this._set, i) ) arr.push(this._set[i]);
  }
  return arr;
};


proto.iterator = function ( ) {
  return new IdIterator(this, this.toArray(), 0);
};



function IdIterator ( parent, elems, index ) {
  this._parent = parent;
  this._elems  = elems;
  this._index  = index;
  this._state_no = parent._state_no;
}

var proto = IdIterator.prototype = new Iterator();
proto.constructor = IdIterator;

proto.isBoundTo = function ( o ) {
  return this._parent === o;
};

proto.isTail = function ( ) {
  if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
  return this._index >= this._elems.length;
};

proto.next = function ( ) {
  if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
  if ( this.isTail() ) throw new NoSuchElementError("no more element after the tail");
  return new IdIterator(this._parent, this._elems, this._index+1);
};

proto.value = function ( ) {
  if ( this._state_no !== this._parent._state_no ) throw new IllegalStateError("parent IdentifierSet object's state has been changed");
  return this._elems[this._index];
};

          return {
              IdentifierSet: IdentifierSet
          };
      }();
  }
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.IdentifierSet = IdentifierSet;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Continuation || (typeof this.Concurrent.Thread.Continuation != 'object' && typeof this.Concurrent.Thread.Continuation != 'function') ) this.Concurrent.Thread.Continuation = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( this.Concurrent.Thread.Continuation.callcc === undefined ) this.Concurrent.Thread.Continuation.callcc = undefined;
  if ( this.Concurrent.Thread.Continuation.getCC === undefined ) this.Concurrent.Thread.Continuation.getCC = undefined;
  if ( this.Concurrent.Thread.Continuation.currentContinuation === undefined ) this.Concurrent.Thread.Continuation.currentContinuation = undefined;
  if ( this.Concurrent.Thread.Continuation.ContinuationCalledException === undefined ) this.Concurrent.Thread.Continuation.ContinuationCalledException = undefined;
with ( function(){
with ( Data.Error ) {
with ( Concurrent.Thread.Continuation ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Continuation';










function callcc ( ) {
  throw new Error("can't call `" + NAMESPACE + ".callcc' in non-threaded functions");
}

callcc.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  function continuation ( ) {
      throw new Error("can't call any captured continuation in non-threaded functions");
  }
  continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
      return { continuation: $cont ,
               timeout     : void 0,
               ret_val     : $args[0] };
  };
  var f = $args[0];
  return f && typeof f.$Concurrent_Thread_compiled === "function"
           ?  f.$Concurrent_Thread_compiled(null, [continuation], $cont)
           :  {continuation:$cont, ret_val:f(continuation), timeout:void 0};
};



function getCC ( ) {
  throw new Error("can't call `" + NAMESPACE + ".getCC' in non-threaded functions");
}

getCC.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  function continuation ( ) {
      throw new Error("can't call any captured continuation in non-threaded functions");
  }
  continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
      return { continuation: $cont ,
               timeout     : void 0,
               ret_val     : $args[0] };
  };
  return {continuation:$cont, ret_val:continuation, timeout:void 0};
};



function currentContinuation ( ) {
  throw new Error("can't call `" + NAMESPACE + ".currentContinuation' in non-threaded functions");
}

currentContinuation.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  function continuation ( ) {
      throw new Error("can't call any captured continuation in non-threaded functions");
  }
  continuation.$Concurrent_Thread_compiled = function ( $this, $args, _ ) {
      return { continuation: $cont.exception,
               timeout     : void 0          ,
               ret_val     : new ContinuationCalledException($args) };
  };
  return { continuation: $cont ,
           timeout     : void 0,
           ret_val     : continuation };
};



var ContinuationCalledException = Exception.extend(
  function ( $super, args ) {
      $super("continuation called");
      this.args = args;
  },
  { name: NAMESPACE + ".ContinuationCalledException" }
);

          return {
              ContinuationCalledException: ContinuationCalledException, callcc: callcc, getCC: getCC, currentContinuation: currentContinuation
          };
      }();
  }
}
}.call(null) ) {
  this.Concurrent.Thread.Continuation.ContinuationCalledException = ContinuationCalledException;
  this.Concurrent.Thread.Continuation.callcc = callcc;
  this.Concurrent.Thread.Continuation.getCC = getCC;
  this.Concurrent.Thread.Continuation.currentContinuation = currentContinuation;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( this.Concurrent.Thread.Compiler.ErrorReporter === undefined ) this.Concurrent.Thread.Compiler.ErrorReporter = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Norris Boyd
*   Daisuke Maki
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

/**
* This file is based on the file ErrorReporter.java in Rhino 1.6R5.
*/

// API class


NAMESPACE = 'Concurrent.Thread.Compiler';



/**
* This is interface defines a protocol for the reporting of
* errors during JavaScript translation or execution.
*
* @author Norris Boyd
*/


function ErrorReporter ( ) {
  // This is kind of abstract class.
  // It provides null-implementations for the methods as default.
}

var proto = ErrorReporter.prototype;


/**
* Report a warning.
*
* The implementing class may choose to ignore the warning
* if it desires.
*
* @param message a String describing the warning
* @param line the line number associated with the warning
* @param lineSource the text of the line (may be null)
* @param lineOffset the offset into lineSource where problem was detected
*/
proto.warning = function ( message, line, lineSource, lineOffset ) { };


/**
* Report an error.
*
* The implementing class is free to throw an exception if
* it desires.
*
* If execution has not yet begun, the JavaScript engine is
* free to find additional errors rather than terminating
* the translation. It will not execute a script that had
* errors, however.
*
* @param message a String describing the error
* @param line the line number associated with the error
* @param lineSource the text of the line (may be null)
* @param lineOffset the offset into lineSource where problem was detected
*/
proto.error   = function ( message, line, lineSource, lineOffset ) { };


          return {
              ErrorReporter: ErrorReporter
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.ErrorReporter = ErrorReporter;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( this.Concurrent.Thread.Compiler.isAlpha === undefined ) this.Concurrent.Thread.Compiler.isAlpha = undefined;
  if ( this.Concurrent.Thread.Compiler.isDigit === undefined ) this.Concurrent.Thread.Compiler.isDigit = undefined;
  if ( this.Concurrent.Thread.Compiler.isHexDigit === undefined ) this.Concurrent.Thread.Compiler.isHexDigit = undefined;
  if ( this.Concurrent.Thread.Compiler.isLineTerminator === undefined ) this.Concurrent.Thread.Compiler.isLineTerminator = undefined;
  if ( this.Concurrent.Thread.Compiler.isSpace === undefined ) this.Concurrent.Thread.Compiler.isSpace = undefined;
  if ( this.Concurrent.Thread.Compiler.isFormatChar === undefined ) this.Concurrent.Thread.Compiler.isFormatChar = undefined;
  if ( this.Concurrent.Thread.Compiler.isIdentifierStart === undefined ) this.Concurrent.Thread.Compiler.isIdentifierStart = undefined;
  if ( this.Concurrent.Thread.Compiler.isIdentifierPart === undefined ) this.Concurrent.Thread.Compiler.isIdentifierPart = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Compiler';





function isAlpha ( c )
{
  c = c.charCodeAt(0);
  // #generated# Last update: Tue, 01 Aug 2006 16:31:50 +0900
  return c <= 0x5A ?
  0x41 <= c :
  0x61 <= c && c <= 0x7A;
  // #/generated#
}



function isDigit ( c )
{
  c = c.charCodeAt(0);
  // #generated# Last update: Tue, 01 Aug 2006 21:02:15 +0900
  return 0x30 <= c && c <= 0x39;
  // #/generated#
}



function isHexDigit  ( c )
{
  c = c.charCodeAt(0);
  // #generated# Last update: Tue, 01 Aug 2006 15:49:52 +0900
  return c <= 0x46 ?
  c <= 0x39 ?
  0x30 <= c :
  0x41 <= c :
  0x61 <= c && c <= 0x66;
  // #/generated#
}



function isLineTerminator ( c ) {
  switch ( c.charCodeAt(0) ) {
  case 0x000A:  // Line Feed           <LF>
  case 0x000D:  // Carriage Return     <CR>
  case 0x2028:  // Line separator      <LS>
  case 0x2029:  // Paragraph separator <PS>
      return true;
  default:
      return false;
  }
}



function isSpace ( c )
{
  c = c.charCodeAt(0);
  if ( c <= 255 ) {
      switch ( c ) {
      case 0x0009:  // Tab            <TAB>
      case 0x000B:  // Vertical Tab   <VT>
      case 0x000C:  // Form Feed      <FF>
      case 0x0020:  // Space          <SP>
      case 0x00A0:  // No-break space <NBSP>
          return true;
      default:
          return false;
      }
  }
  else {
      // the following code is derived from the Unicode category Zs based on:
      // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
      // #generated# Last update: Tue, 01 Aug 2006 01:57:18 +0900
      return c <= 0x180E ?
      c <= 0xA0 ?
      c <= 0x20 ?
      0x20 <= c :
      0xA0 <= c :
      c <= 0x1680 ?
      0x1680 <= c :
      0x180E <= c :
      c <= 0x202F ?
      c <= 0x200A ?
      0x2000 <= c :
      0x202F <= c :
      c <= 0x205F ?
      0x205F <= c :
      c === 0x3000;
      // #/generated#
  }
}



function isFormatChar ( c )
{
  c = c.charCodeAt(0);
  if ( c <= 127 ) return false;  // optimization for ASCII characters
  // the following code is derived from the Unicode category Cf based on:
  // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
  // #generated# Last update: Tue, 01 Aug 2006 01:50:39 +0900
  return c <= 0x202E ?
  c <= 0x70F ?
  c <= 0x603 ?
  c <= 0xAD ?
  0xAD <= c :
  0x600 <= c :
  c <= 0x6DD ?
  0x6DD <= c :
  0x70F <= c :
  c <= 0x200F ?
  c <= 0x17B5 ?
  0x17B4 <= c :
  0x200B <= c :
  0x202A <= c :
  c <= 0xFFFB ?
  c <= 0x206F ?
  c <= 0x2063 ?
  0x2060 <= c :
  0x206A <= c :
  c <= 0xFEFF ?
  0xFEFF <= c :
  0xFFF9 <= c :
  c <= 0xE0001 ?
  c <= 0x1D17A ?
  0x1D173 <= c :
  0xE0001 <= c :
  0xE0020 <= c && c <= 0xE007F;
  // #/generated#
}



function isIdentifierStart ( c ) {
  var c = c.charCodeAt(0);
  switch ( c ) {
  case 0x24:  // '$'
  case 0x5F:  // '_'
      return true;
  }
  // the following code is derived from the Unicode category Lu, Ll, Lt, Lm, Lo, and Nl based on:
  // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
  // #generated# Last update: Tue, 01 Aug 2006 01:47:30 +0900
  return c <= 0x1731 ?
  c <= 0xB95 ?
  c <= 0x961 ?
  c <= 0x587 ?
  c <= 0x37D ?
  c <= 0xD6 ?
  c <= 0xAA ?
  c <= 0x7A ?
  c <= 0x5A ?
  0x41 <= c :
  0x61 <= c :
  0xAA <= c :
  c <= 0xBA ?
  c <= 0xB5 ?
  0xB5 <= c :
  0xBA <= c :
  0xC0 <= c :
  c <= 0x2D1 ?
  c <= 0x2C1 ?
  c <= 0xF6 ?
  0xD8 <= c :
  0xF8 <= c :
  0x2C6 <= c :
  c <= 0x2EE ?
  c <= 0x2E4 ?
  0x2E0 <= c :
  0x2EE <= c :
  0x37A <= c :
  c <= 0x3F5 ?
  c <= 0x38C ?
  c <= 0x38A ?
  c <= 0x386 ?
  0x386 <= c :
  0x388 <= c :
  0x38C <= c :
  c <= 0x3CE ?
  c <= 0x3A1 ?
  0x38E <= c :
  0x3A3 <= c :
  0x3D0 <= c :
  c <= 0x556 ?
  c <= 0x513 ?
  c <= 0x481 ?
  0x3F7 <= c :
  0x48A <= c :
  0x531 <= c :
  c <= 0x559 ?
  0x559 <= c :
  0x561 <= c :
  c <= 0x710 ?
  c <= 0x6D3 ?
  c <= 0x63A ?
  c <= 0x5F2 ?
  c <= 0x5EA ?
  0x5D0 <= c :
  0x5F0 <= c :
  0x621 <= c :
  c <= 0x66F ?
  c <= 0x64A ?
  0x640 <= c :
  0x66E <= c :
  0x671 <= c :
  c <= 0x6EF ?
  c <= 0x6E6 ?
  c <= 0x6D5 ?
  0x6D5 <= c :
  0x6E5 <= c :
  0x6EE <= c :
  c <= 0x6FF ?
  c <= 0x6FC ?
  0x6FA <= c :
  0x6FF <= c :
  0x710 <= c :
  c <= 0x7F5 ?
  c <= 0x7A5 ?
  c <= 0x76D ?
  c <= 0x72F ?
  0x712 <= c :
  0x74D <= c :
  0x780 <= c :
  c <= 0x7EA ?
  c <= 0x7B1 ?
  0x7B1 <= c :
  0x7CA <= c :
  0x7F4 <= c :
  c <= 0x93D ?
  c <= 0x939 ?
  c <= 0x7FA ?
  0x7FA <= c :
  0x904 <= c :
  0x93D <= c :
  c <= 0x950 ?
  0x950 <= c :
  0x958 <= c :
  c <= 0xA8D ?
  c <= 0x9F1 ?
  c <= 0x9B2 ?
  c <= 0x990 ?
  c <= 0x98C ?
  c <= 0x97F ?
  0x97B <= c :
  0x985 <= c :
  0x98F <= c :
  c <= 0x9B0 ?
  c <= 0x9A8 ?
  0x993 <= c :
  0x9AA <= c :
  0x9B2 <= c :
  c <= 0x9CE ?
  c <= 0x9BD ?
  c <= 0x9B9 ?
  0x9B6 <= c :
  0x9BD <= c :
  0x9CE <= c :
  c <= 0x9E1 ?
  c <= 0x9DD ?
  0x9DC <= c :
  0x9DF <= c :
  0x9F0 <= c :
  c <= 0xA36 ?
  c <= 0xA28 ?
  c <= 0xA10 ?
  c <= 0xA0A ?
  0xA05 <= c :
  0xA0F <= c :
  0xA13 <= c :
  c <= 0xA33 ?
  c <= 0xA30 ?
  0xA2A <= c :
  0xA32 <= c :
  0xA35 <= c :
  c <= 0xA5E ?
  c <= 0xA5C ?
  c <= 0xA39 ?
  0xA38 <= c :
  0xA59 <= c :
  0xA5E <= c :
  c <= 0xA74 ?
  0xA72 <= c :
  0xA85 <= c :
  c <= 0xB28 ?
  c <= 0xABD ?
  c <= 0xAB0 ?
  c <= 0xAA8 ?
  c <= 0xA91 ?
  0xA8F <= c :
  0xA93 <= c :
  0xAAA <= c :
  c <= 0xAB9 ?
  c <= 0xAB3 ?
  0xAB2 <= c :
  0xAB5 <= c :
  0xABD <= c :
  c <= 0xB0C ?
  c <= 0xAE1 ?
  c <= 0xAD0 ?
  0xAD0 <= c :
  0xAE0 <= c :
  0xB05 <= c :
  c <= 0xB10 ?
  0xB0F <= c :
  0xB13 <= c :
  c <= 0xB61 ?
  c <= 0xB39 ?
  c <= 0xB33 ?
  c <= 0xB30 ?
  0xB2A <= c :
  0xB32 <= c :
  0xB35 <= c :
  c <= 0xB5D ?
  c <= 0xB3D ?
  0xB3D <= c :
  0xB5C <= c :
  0xB5F <= c :
  c <= 0xB8A ?
  c <= 0xB83 ?
  c <= 0xB71 ?
  0xB71 <= c :
  0xB83 <= c :
  0xB85 <= c :
  c <= 0xB90 ?
  0xB8E <= c :
  0xB92 <= c :
  c <= 0xEB0 ?
  c <= 0xD28 ?
  c <= 0xC61 ?
  c <= 0xBB9 ?
  c <= 0xB9F ?
  c <= 0xB9C ?
  c <= 0xB9A ?
  0xB99 <= c :
  0xB9C <= c :
  0xB9E <= c :
  c <= 0xBAA ?
  c <= 0xBA4 ?
  0xBA3 <= c :
  0xBA8 <= c :
  0xBAE <= c :
  c <= 0xC28 ?
  c <= 0xC10 ?
  c <= 0xC0C ?
  0xC05 <= c :
  0xC0E <= c :
  0xC12 <= c :
  c <= 0xC39 ?
  c <= 0xC33 ?
  0xC2A <= c :
  0xC35 <= c :
  0xC60 <= c :
  c <= 0xCBD ?
  c <= 0xCA8 ?
  c <= 0xC90 ?
  c <= 0xC8C ?
  0xC85 <= c :
  0xC8E <= c :
  0xC92 <= c :
  c <= 0xCB9 ?
  c <= 0xCB3 ?
  0xCAA <= c :
  0xCB5 <= c :
  0xCBD <= c :
  c <= 0xD0C ?
  c <= 0xCE1 ?
  c <= 0xCDE ?
  0xCDE <= c :
  0xCE0 <= c :
  0xD05 <= c :
  c <= 0xD10 ?
  0xD0E <= c :
  0xD12 <= c :
  c <= 0xE82 ?
  c <= 0xDBD ?
  c <= 0xD96 ?
  c <= 0xD61 ?
  c <= 0xD39 ?
  0xD2A <= c :
  0xD60 <= c :
  0xD85 <= c :
  c <= 0xDBB ?
  c <= 0xDB1 ?
  0xD9A <= c :
  0xDB3 <= c :
  0xDBD <= c :
  c <= 0xE33 ?
  c <= 0xE30 ?
  c <= 0xDC6 ?
  0xDC0 <= c :
  0xE01 <= c :
  0xE32 <= c :
  c <= 0xE46 ?
  0xE40 <= c :
  0xE81 <= c :
  c <= 0xE9F ?
  c <= 0xE8A ?
  c <= 0xE88 ?
  c <= 0xE84 ?
  0xE84 <= c :
  0xE87 <= c :
  0xE8A <= c :
  c <= 0xE97 ?
  c <= 0xE8D ?
  0xE8D <= c :
  0xE94 <= c :
  0xE99 <= c :
  c <= 0xEA7 ?
  c <= 0xEA5 ?
  c <= 0xEA3 ?
  0xEA1 <= c :
  0xEA5 <= c :
  0xEA7 <= c :
  c <= 0xEAB ?
  0xEAA <= c :
  0xEAD <= c :
  c <= 0x1258 ?
  c <= 0x102A ?
  c <= 0xF00 ?
  c <= 0xEC4 ?
  c <= 0xEBD ?
  c <= 0xEB3 ?
  0xEB2 <= c :
  0xEBD <= c :
  0xEC0 <= c :
  c <= 0xEDD ?
  c <= 0xEC6 ?
  0xEC6 <= c :
  0xEDC <= c :
  0xF00 <= c :
  c <= 0xF8B ?
  c <= 0xF6A ?
  c <= 0xF47 ?
  0xF40 <= c :
  0xF49 <= c :
  0xF88 <= c :
  c <= 0x1027 ?
  c <= 0x1021 ?
  0x1000 <= c :
  0x1023 <= c :
  0x1029 <= c :
  c <= 0x11A2 ?
  c <= 0x10FA ?
  c <= 0x10C5 ?
  c <= 0x1055 ?
  0x1050 <= c :
  0x10A0 <= c :
  0x10D0 <= c :
  c <= 0x1159 ?
  c <= 0x10FC ?
  0x10FC <= c :
  0x1100 <= c :
  0x115F <= c :
  c <= 0x124D ?
  c <= 0x1248 ?
  c <= 0x11F9 ?
  0x11A8 <= c :
  0x1200 <= c :
  0x124A <= c :
  c <= 0x1256 ?
  0x1250 <= c :
  0x1258 <= c :
  c <= 0x1315 ?
  c <= 0x12BE ?
  c <= 0x128D ?
  c <= 0x1288 ?
  c <= 0x125D ?
  0x125A <= c :
  0x1260 <= c :
  0x128A <= c :
  c <= 0x12B5 ?
  c <= 0x12B0 ?
  0x1290 <= c :
  0x12B2 <= c :
  0x12B8 <= c :
  c <= 0x12D6 ?
  c <= 0x12C5 ?
  c <= 0x12C0 ?
  0x12C0 <= c :
  0x12C2 <= c :
  0x12C8 <= c :
  c <= 0x1310 ?
  0x12D8 <= c :
  0x1312 <= c :
  c <= 0x169A ?
  c <= 0x13F4 ?
  c <= 0x138F ?
  c <= 0x135A ?
  0x1318 <= c :
  0x1380 <= c :
  0x13A0 <= c :
  c <= 0x1676 ?
  c <= 0x166C ?
  0x1401 <= c :
  0x166F <= c :
  0x1681 <= c :
  c <= 0x170C ?
  c <= 0x16F0 ?
  c <= 0x16EA ?
  0x16A0 <= c :
  0x16EE <= c :
  0x1700 <= c :
  c <= 0x1711 ?
  0x170E <= c :
  0x1720 <= c :
  c <= 0xA805 ?
  c <= 0x2115 ?
  c <= 0x1F4D ?
  c <= 0x19A9 ?
  c <= 0x17DC ?
  c <= 0x1770 ?
  c <= 0x176C ?
  c <= 0x1751 ?
  0x1740 <= c :
  0x1760 <= c :
  0x176E <= c :
  c <= 0x17D7 ?
  c <= 0x17B3 ?
  0x1780 <= c :
  0x17D7 <= c :
  0x17DC <= c :
  c <= 0x191C ?
  c <= 0x18A8 ?
  c <= 0x1877 ?
  0x1820 <= c :
  0x1880 <= c :
  0x1900 <= c :
  c <= 0x1974 ?
  c <= 0x196D ?
  0x1950 <= c :
  0x1970 <= c :
  0x1980 <= c :
  c <= 0x1E9B ?
  c <= 0x1B33 ?
  c <= 0x1A16 ?
  c <= 0x19C7 ?
  0x19C1 <= c :
  0x1A00 <= c :
  0x1B05 <= c :
  c <= 0x1DBF ?
  c <= 0x1B4B ?
  0x1B45 <= c :
  0x1D00 <= c :
  0x1E00 <= c :
  c <= 0x1F1D ?
  c <= 0x1F15 ?
  c <= 0x1EF9 ?
  0x1EA0 <= c :
  0x1F00 <= c :
  0x1F18 <= c :
  c <= 0x1F45 ?
  0x1F20 <= c :
  0x1F48 <= c :
  c <= 0x1FD3 ?
  c <= 0x1FB4 ?
  c <= 0x1F5B ?
  c <= 0x1F59 ?
  c <= 0x1F57 ?
  0x1F50 <= c :
  0x1F59 <= c :
  0x1F5B <= c :
  c <= 0x1F7D ?
  c <= 0x1F5D ?
  0x1F5D <= c :
  0x1F5F <= c :
  0x1F80 <= c :
  c <= 0x1FC4 ?
  c <= 0x1FBE ?
  c <= 0x1FBC ?
  0x1FB6 <= c :
  0x1FBE <= c :
  0x1FC2 <= c :
  c <= 0x1FCC ?
  0x1FC6 <= c :
  0x1FD0 <= c :
  c <= 0x207F ?
  c <= 0x1FF4 ?
  c <= 0x1FEC ?
  c <= 0x1FDB ?
  0x1FD6 <= c :
  0x1FE0 <= c :
  0x1FF2 <= c :
  c <= 0x2071 ?
  c <= 0x1FFC ?
  0x1FF6 <= c :
  0x2071 <= c :
  0x207F <= c :
  c <= 0x2107 ?
  c <= 0x2102 ?
  c <= 0x2094 ?
  0x2090 <= c :
  0x2102 <= c :
  0x2107 <= c :
  c <= 0x2113 ?
  0x210A <= c :
  0x2115 <= c :
  c <= 0x2DBE ?
  c <= 0x2C5E ?
  c <= 0x2139 ?
  c <= 0x2126 ?
  c <= 0x2124 ?
  c <= 0x211D ?
  0x2119 <= c :
  0x2124 <= c :
  0x2126 <= c :
  c <= 0x212D ?
  c <= 0x2128 ?
  0x2128 <= c :
  0x212A <= c :
  0x212F <= c :
  c <= 0x214E ?
  c <= 0x2149 ?
  c <= 0x213F ?
  0x213C <= c :
  0x2145 <= c :
  0x214E <= c :
  c <= 0x2C2E ?
  c <= 0x2184 ?
  0x2160 <= c :
  0x2C00 <= c :
  0x2C30 <= c :
  c <= 0x2D6F ?
  c <= 0x2CE4 ?
  c <= 0x2C77 ?
  c <= 0x2C6C ?
  0x2C60 <= c :
  0x2C74 <= c :
  0x2C80 <= c :
  c <= 0x2D65 ?
  c <= 0x2D25 ?
  0x2D00 <= c :
  0x2D30 <= c :
  0x2D6F <= c :
  c <= 0x2DAE ?
  c <= 0x2DA6 ?
  c <= 0x2D96 ?
  0x2D80 <= c :
  0x2DA0 <= c :
  0x2DA8 <= c :
  c <= 0x2DB6 ?
  0x2DB0 <= c :
  0x2DB8 <= c :
  c <= 0x30FA ?
  c <= 0x3029 ?
  c <= 0x2DD6 ?
  c <= 0x2DCE ?
  c <= 0x2DC6 ?
  0x2DC0 <= c :
  0x2DC8 <= c :
  0x2DD0 <= c :
  c <= 0x3007 ?
  c <= 0x2DDE ?
  0x2DD8 <= c :
  0x3005 <= c :
  0x3021 <= c :
  c <= 0x3096 ?
  c <= 0x303C ?
  c <= 0x3035 ?
  0x3031 <= c :
  0x3038 <= c :
  0x3041 <= c :
  c <= 0x309F ?
  0x309D <= c :
  0x30A1 <= c :
  c <= 0x4DB5 ?
  c <= 0x318E ?
  c <= 0x312C ?
  c <= 0x30FF ?
  0x30FC <= c :
  0x3105 <= c :
  0x3131 <= c :
  c <= 0x31FF ?
  c <= 0x31B7 ?
  0x31A0 <= c :
  0x31F0 <= c :
  0x3400 <= c :
  c <= 0xA71A ?
  c <= 0xA48C ?
  c <= 0x9FBB ?
  0x4E00 <= c :
  0xA000 <= c :
  0xA717 <= c :
  c <= 0xA801 ?
  0xA800 <= c :
  0xA803 <= c :
  c <= 0x1049D ?
  c <= 0xFEFC ?
  c <= 0xFB36 ?
  c <= 0xFA6A ?
  c <= 0xA873 ?
  c <= 0xA822 ?
  c <= 0xA80A ?
  0xA807 <= c :
  0xA80C <= c :
  0xA840 <= c :
  c <= 0xFA2D ?
  c <= 0xD7A3 ?
  0xAC00 <= c :
  0xF900 <= c :
  0xFA30 <= c :
  c <= 0xFB17 ?
  c <= 0xFB06 ?
  c <= 0xFAD9 ?
  0xFA70 <= c :
  0xFB00 <= c :
  0xFB13 <= c :
  c <= 0xFB28 ?
  c <= 0xFB1D ?
  0xFB1D <= c :
  0xFB1F <= c :
  0xFB2A <= c :
  c <= 0xFD3D ?
  c <= 0xFB41 ?
  c <= 0xFB3E ?
  c <= 0xFB3C ?
  0xFB38 <= c :
  0xFB3E <= c :
  0xFB40 <= c :
  c <= 0xFBB1 ?
  c <= 0xFB44 ?
  0xFB43 <= c :
  0xFB46 <= c :
  0xFBD3 <= c :
  c <= 0xFDFB ?
  c <= 0xFDC7 ?
  c <= 0xFD8F ?
  0xFD50 <= c :
  0xFD92 <= c :
  0xFDF0 <= c :
  c <= 0xFE74 ?
  0xFE70 <= c :
  0xFE76 <= c :
  c <= 0x1003D ?
  c <= 0xFFD7 ?
  c <= 0xFFBE ?
  c <= 0xFF5A ?
  c <= 0xFF3A ?
  0xFF21 <= c :
  0xFF41 <= c :
  0xFF66 <= c :
  c <= 0xFFCF ?
  c <= 0xFFC7 ?
  0xFFC2 <= c :
  0xFFCA <= c :
  0xFFD2 <= c :
  c <= 0x10026 ?
  c <= 0x1000B ?
  c <= 0xFFDC ?
  0xFFDA <= c :
  0x10000 <= c :
  0x1000D <= c :
  c <= 0x1003A ?
  0x10028 <= c :
  0x1003C <= c :
  c <= 0x1034A ?
  c <= 0x100FA ?
  c <= 0x1005D ?
  c <= 0x1004D ?
  0x1003F <= c :
  0x10050 <= c :
  0x10080 <= c :
  c <= 0x1031E ?
  c <= 0x10174 ?
  0x10140 <= c :
  0x10300 <= c :
  0x10330 <= c :
  c <= 0x103CF ?
  c <= 0x103C3 ?
  c <= 0x1039D ?
  0x10380 <= c :
  0x103A0 <= c :
  0x103C8 <= c :
  c <= 0x103D5 ?
  0x103D1 <= c :
  0x10400 <= c :
  c <= 0x1D505 ?
  c <= 0x1236E ?
  c <= 0x1083F ?
  c <= 0x10835 ?
  c <= 0x10808 ?
  c <= 0x10805 ?
  0x10800 <= c :
  0x10808 <= c :
  0x1080A <= c :
  c <= 0x1083C ?
  c <= 0x10838 ?
  0x10837 <= c :
  0x1083C <= c :
  0x1083F <= c :
  c <= 0x10A13 ?
  c <= 0x10A00 ?
  c <= 0x10915 ?
  0x10900 <= c :
  0x10A00 <= c :
  0x10A10 <= c :
  c <= 0x10A33 ?
  c <= 0x10A17 ?
  0x10A15 <= c :
  0x10A19 <= c :
  0x12000 <= c :
  c <= 0x1D4A6 ?
  c <= 0x1D49C ?
  c <= 0x1D454 ?
  c <= 0x12462 ?
  0x12400 <= c :
  0x1D400 <= c :
  0x1D456 <= c :
  c <= 0x1D4A2 ?
  c <= 0x1D49F ?
  0x1D49E <= c :
  0x1D4A2 <= c :
  0x1D4A5 <= c :
  c <= 0x1D4BB ?
  c <= 0x1D4B9 ?
  c <= 0x1D4AC ?
  0x1D4A9 <= c :
  0x1D4AE <= c :
  0x1D4BB <= c :
  c <= 0x1D4C3 ?
  0x1D4BD <= c :
  0x1D4C5 <= c :
  c <= 0x1D6DA ?
  c <= 0x1D544 ?
  c <= 0x1D51C ?
  c <= 0x1D514 ?
  c <= 0x1D50A ?
  0x1D507 <= c :
  0x1D50D <= c :
  0x1D516 <= c :
  c <= 0x1D53E ?
  c <= 0x1D539 ?
  0x1D51E <= c :
  0x1D53B <= c :
  0x1D540 <= c :
  c <= 0x1D6A5 ?
  c <= 0x1D550 ?
  c <= 0x1D546 ?
  0x1D546 <= c :
  0x1D54A <= c :
  0x1D552 <= c :
  c <= 0x1D6C0 ?
  0x1D6A8 <= c :
  0x1D6C2 <= c :
  c <= 0x1D788 ?
  c <= 0x1D734 ?
  c <= 0x1D714 ?
  c <= 0x1D6FA ?
  0x1D6DC <= c :
  0x1D6FC <= c :
  0x1D716 <= c :
  c <= 0x1D76E ?
  c <= 0x1D74E ?
  0x1D736 <= c :
  0x1D750 <= c :
  0x1D770 <= c :
  c <= 0x1D7CB ?
  c <= 0x1D7C2 ?
  c <= 0x1D7A8 ?
  0x1D78A <= c :
  0x1D7AA <= c :
  0x1D7C4 <= c :
  c <= 0x2A6D6 ?
  0x20000 <= c :
  0x2F800 <= c && c <= 0x2FA1D;
  // #/generated#
}



function isIdentifierPart ( c ) {
  var c = c.charCodeAt(0);
  switch ( c ) {
  case 0x24:  // '$'
  case 0x5F:  // '_'
      return true;
  }
  // the following code is derived from the Unicode category Lu, Ll, Lt, Lm, Lo, Nl, Mn, Mc, Nd, and Pc based on:
  // http://www.unicode.org/Public/UNIDATA/extracted/DerivedGeneralCategory.txt
  // #generated# Last update: Tue, 01 Aug 2006 02:00:01 +0900
  return c <= 0x12B0 ?
  c <= 0xB90 ?
  c <= 0x990 ?
  c <= 0x5BF ?
  c <= 0x37D ?
  c <= 0xD6 ?
  c <= 0x7A ?
  c <= 0x5A ?
  c <= 0x39 ?
  0x30 <= c :
  0x41 <= c :
  c <= 0x5F ?
  0x5F <= c :
  0x61 <= c :
  c <= 0xB5 ?
  c <= 0xAA ?
  0xAA <= c :
  0xB5 <= c :
  c <= 0xBA ?
  0xBA <= c :
  0xC0 <= c :
  c <= 0x2E4 ?
  c <= 0x2C1 ?
  c <= 0xF6 ?
  0xD8 <= c :
  0xF8 <= c :
  c <= 0x2D1 ?
  0x2C6 <= c :
  0x2E0 <= c :
  c <= 0x36F ?
  c <= 0x2EE ?
  0x2EE <= c :
  0x300 <= c :
  0x37A <= c :
  c <= 0x481 ?
  c <= 0x3A1 ?
  c <= 0x38A ?
  c <= 0x386 ?
  0x386 <= c :
  0x388 <= c :
  c <= 0x38C ?
  0x38C <= c :
  0x38E <= c :
  c <= 0x3F5 ?
  c <= 0x3CE ?
  0x3A3 <= c :
  0x3D0 <= c :
  0x3F7 <= c :
  c <= 0x559 ?
  c <= 0x513 ?
  c <= 0x486 ?
  0x483 <= c :
  0x48A <= c :
  c <= 0x556 ?
  0x531 <= c :
  0x559 <= c :
  c <= 0x5BD ?
  c <= 0x587 ?
  0x561 <= c :
  0x591 <= c :
  0x5BF <= c :
  c <= 0x6FF ?
  c <= 0x63A ?
  c <= 0x5EA ?
  c <= 0x5C5 ?
  c <= 0x5C2 ?
  0x5C1 <= c :
  0x5C4 <= c :
  c <= 0x5C7 ?
  0x5C7 <= c :
  0x5D0 <= c :
  c <= 0x615 ?
  c <= 0x5F2 ?
  0x5F0 <= c :
  0x610 <= c :
  0x621 <= c :
  c <= 0x6DC ?
  c <= 0x669 ?
  c <= 0x65E ?
  0x640 <= c :
  0x660 <= c :
  c <= 0x6D3 ?
  0x66E <= c :
  0x6D5 <= c :
  c <= 0x6FC ?
  c <= 0x6E8 ?
  0x6DF <= c :
  0x6EA <= c :
  0x6FF <= c :
  c <= 0x94D ?
  c <= 0x7F5 ?
  c <= 0x76D ?
  c <= 0x74A ?
  0x710 <= c :
  0x74D <= c :
  c <= 0x7B1 ?
  0x780 <= c :
  0x7C0 <= c :
  c <= 0x939 ?
  c <= 0x7FA ?
  0x7FA <= c :
  0x901 <= c :
  0x93C <= c :
  c <= 0x97F ?
  c <= 0x963 ?
  c <= 0x954 ?
  0x950 <= c :
  0x958 <= c :
  c <= 0x96F ?
  0x966 <= c :
  0x97B <= c :
  c <= 0x98C ?
  c <= 0x983 ?
  0x981 <= c :
  0x985 <= c :
  0x98F <= c :
  c <= 0xA91 ?
  c <= 0xA28 ?
  c <= 0x9D7 ?
  c <= 0x9B9 ?
  c <= 0x9B0 ?
  c <= 0x9A8 ?
  0x993 <= c :
  0x9AA <= c :
  c <= 0x9B2 ?
  0x9B2 <= c :
  0x9B6 <= c :
  c <= 0x9C8 ?
  c <= 0x9C4 ?
  0x9BC <= c :
  0x9C7 <= c :
  c <= 0x9CE ?
  0x9CB <= c :
  0x9D7 <= c :
  c <= 0xA03 ?
  c <= 0x9E3 ?
  c <= 0x9DD ?
  0x9DC <= c :
  0x9DF <= c :
  c <= 0x9F1 ?
  0x9E6 <= c :
  0xA01 <= c :
  c <= 0xA10 ?
  c <= 0xA0A ?
  0xA05 <= c :
  0xA0F <= c :
  0xA13 <= c :
  c <= 0xA48 ?
  c <= 0xA39 ?
  c <= 0xA33 ?
  c <= 0xA30 ?
  0xA2A <= c :
  0xA32 <= c :
  c <= 0xA36 ?
  0xA35 <= c :
  0xA38 <= c :
  c <= 0xA42 ?
  c <= 0xA3C ?
  0xA3C <= c :
  0xA3E <= c :
  0xA47 <= c :
  c <= 0xA74 ?
  c <= 0xA5C ?
  c <= 0xA4D ?
  0xA4B <= c :
  0xA59 <= c :
  c <= 0xA5E ?
  0xA5E <= c :
  0xA66 <= c :
  c <= 0xA8D ?
  c <= 0xA83 ?
  0xA81 <= c :
  0xA85 <= c :
  0xA8F <= c :
  c <= 0xB28 ?
  c <= 0xACD ?
  c <= 0xAB9 ?
  c <= 0xAB0 ?
  c <= 0xAA8 ?
  0xA93 <= c :
  0xAAA <= c :
  c <= 0xAB3 ?
  0xAB2 <= c :
  0xAB5 <= c :
  c <= 0xAC9 ?
  c <= 0xAC5 ?
  0xABC <= c :
  0xAC7 <= c :
  0xACB <= c :
  c <= 0xB03 ?
  c <= 0xAE3 ?
  c <= 0xAD0 ?
  0xAD0 <= c :
  0xAE0 <= c :
  c <= 0xAEF ?
  0xAE6 <= c :
  0xB01 <= c :
  c <= 0xB10 ?
  c <= 0xB0C ?
  0xB05 <= c :
  0xB0F <= c :
  0xB13 <= c :
  c <= 0xB57 ?
  c <= 0xB43 ?
  c <= 0xB33 ?
  c <= 0xB30 ?
  0xB2A <= c :
  0xB32 <= c :
  c <= 0xB39 ?
  0xB35 <= c :
  0xB3C <= c :
  c <= 0xB4D ?
  c <= 0xB48 ?
  0xB47 <= c :
  0xB4B <= c :
  0xB56 <= c :
  c <= 0xB71 ?
  c <= 0xB61 ?
  c <= 0xB5D ?
  0xB5C <= c :
  0xB5F <= c :
  c <= 0xB6F ?
  0xB66 <= c :
  0xB71 <= c :
  c <= 0xB8A ?
  c <= 0xB83 ?
  0xB82 <= c :
  0xB85 <= c :
  0xB8E <= c :
  c <= 0xDD6 ?
  c <= 0xCB3 ?
  c <= 0xC10 ?
  c <= 0xBC2 ?
  c <= 0xB9F ?
  c <= 0xB9A ?
  c <= 0xB95 ?
  0xB92 <= c :
  0xB99 <= c :
  c <= 0xB9C ?
  0xB9C <= c :
  0xB9E <= c :
  c <= 0xBAA ?
  c <= 0xBA4 ?
  0xBA3 <= c :
  0xBA8 <= c :
  c <= 0xBB9 ?
  0xBAE <= c :
  0xBBE <= c :
  c <= 0xBEF ?
  c <= 0xBCD ?
  c <= 0xBC8 ?
  0xBC6 <= c :
  0xBCA <= c :
  c <= 0xBD7 ?
  0xBD7 <= c :
  0xBE6 <= c :
  c <= 0xC0C ?
  c <= 0xC03 ?
  0xC01 <= c :
  0xC05 <= c :
  0xC0E <= c :
  c <= 0xC56 ?
  c <= 0xC44 ?
  c <= 0xC33 ?
  c <= 0xC28 ?
  0xC12 <= c :
  0xC2A <= c :
  c <= 0xC39 ?
  0xC35 <= c :
  0xC3E <= c :
  c <= 0xC4D ?
  c <= 0xC48 ?
  0xC46 <= c :
  0xC4A <= c :
  0xC55 <= c :
  c <= 0xC8C ?
  c <= 0xC6F ?
  c <= 0xC61 ?
  0xC60 <= c :
  0xC66 <= c :
  c <= 0xC83 ?
  0xC82 <= c :
  0xC85 <= c :
  c <= 0xCA8 ?
  c <= 0xC90 ?
  0xC8E <= c :
  0xC92 <= c :
  0xCAA <= c :
  c <= 0xD43 ?
  c <= 0xCE3 ?
  c <= 0xCCD ?
  c <= 0xCC4 ?
  c <= 0xCB9 ?
  0xCB5 <= c :
  0xCBC <= c :
  c <= 0xCC8 ?
  0xCC6 <= c :
  0xCCA <= c :
  c <= 0xCDE ?
  c <= 0xCD6 ?
  0xCD5 <= c :
  0xCDE <= c :
  0xCE0 <= c :
  c <= 0xD10 ?
  c <= 0xD03 ?
  c <= 0xCEF ?
  0xCE6 <= c :
  0xD02 <= c :
  c <= 0xD0C ?
  0xD05 <= c :
  0xD0E <= c :
  c <= 0xD39 ?
  c <= 0xD28 ?
  0xD12 <= c :
  0xD2A <= c :
  0xD3E <= c :
  c <= 0xD96 ?
  c <= 0xD61 ?
  c <= 0xD4D ?
  c <= 0xD48 ?
  0xD46 <= c :
  0xD4A <= c :
  c <= 0xD57 ?
  0xD57 <= c :
  0xD60 <= c :
  c <= 0xD83 ?
  c <= 0xD6F ?
  0xD66 <= c :
  0xD82 <= c :
  0xD85 <= c :
  c <= 0xDC6 ?
  c <= 0xDBB ?
  c <= 0xDB1 ?
  0xD9A <= c :
  0xDB3 <= c :
  c <= 0xDBD ?
  0xDBD <= c :
  0xDC0 <= c :
  c <= 0xDD4 ?
  c <= 0xDCA ?
  0xDCA <= c :
  0xDCF <= c :
  0xDD6 <= c :
  c <= 0xF39 ?
  c <= 0xEA7 ?
  c <= 0xE88 ?
  c <= 0xE4E ?
  c <= 0xDF3 ?
  c <= 0xDDF ?
  0xDD8 <= c :
  0xDF2 <= c :
  c <= 0xE3A ?
  0xE01 <= c :
  0xE40 <= c :
  c <= 0xE82 ?
  c <= 0xE59 ?
  0xE50 <= c :
  0xE81 <= c :
  c <= 0xE84 ?
  0xE84 <= c :
  0xE87 <= c :
  c <= 0xE9F ?
  c <= 0xE8D ?
  c <= 0xE8A ?
  0xE8A <= c :
  0xE8D <= c :
  c <= 0xE97 ?
  0xE94 <= c :
  0xE99 <= c :
  c <= 0xEA5 ?
  c <= 0xEA3 ?
  0xEA1 <= c :
  0xEA5 <= c :
  0xEA7 <= c :
  c <= 0xED9 ?
  c <= 0xEC4 ?
  c <= 0xEB9 ?
  c <= 0xEAB ?
  0xEAA <= c :
  0xEAD <= c :
  c <= 0xEBD ?
  0xEBB <= c :
  0xEC0 <= c :
  c <= 0xECD ?
  c <= 0xEC6 ?
  0xEC6 <= c :
  0xEC8 <= c :
  0xED0 <= c :
  c <= 0xF29 ?
  c <= 0xF00 ?
  c <= 0xEDD ?
  0xEDC <= c :
  0xF00 <= c :
  c <= 0xF19 ?
  0xF18 <= c :
  0xF20 <= c :
  c <= 0xF37 ?
  c <= 0xF35 ?
  0xF35 <= c :
  0xF37 <= c :
  0xF39 <= c :
  c <= 0x1059 ?
  c <= 0xFC6 ?
  c <= 0xF8B ?
  c <= 0xF6A ?
  c <= 0xF47 ?
  0xF3E <= c :
  0xF49 <= c :
  c <= 0xF84 ?
  0xF71 <= c :
  0xF86 <= c :
  c <= 0xFBC ?
  c <= 0xF97 ?
  0xF90 <= c :
  0xF99 <= c :
  0xFC6 <= c :
  c <= 0x1032 ?
  c <= 0x1027 ?
  c <= 0x1021 ?
  0x1000 <= c :
  0x1023 <= c :
  c <= 0x102A ?
  0x1029 <= c :
  0x102C <= c :
  c <= 0x1049 ?
  c <= 0x1039 ?
  0x1036 <= c :
  0x1040 <= c :
  0x1050 <= c :
  c <= 0x1248 ?
  c <= 0x1159 ?
  c <= 0x10FA ?
  c <= 0x10C5 ?
  0x10A0 <= c :
  0x10D0 <= c :
  c <= 0x10FC ?
  0x10FC <= c :
  0x1100 <= c :
  c <= 0x11F9 ?
  c <= 0x11A2 ?
  0x115F <= c :
  0x11A8 <= c :
  0x1200 <= c :
  c <= 0x125D ?
  c <= 0x1256 ?
  c <= 0x124D ?
  0x124A <= c :
  0x1250 <= c :
  c <= 0x1258 ?
  0x1258 <= c :
  0x125A <= c :
  c <= 0x128D ?
  c <= 0x1288 ?
  0x1260 <= c :
  0x128A <= c :
  0x1290 <= c :
  c <= 0x30FF ?
  c <= 0x1FB4 ?
  c <= 0x180D ?
  c <= 0x16EA ?
  c <= 0x135A ?
  c <= 0x12C5 ?
  c <= 0x12BE ?
  c <= 0x12B5 ?
  0x12B2 <= c :
  0x12B8 <= c :
  c <= 0x12C0 ?
  0x12C0 <= c :
  0x12C2 <= c :
  c <= 0x1310 ?
  c <= 0x12D6 ?
  0x12C8 <= c :
  0x12D8 <= c :
  c <= 0x1315 ?
  0x1312 <= c :
  0x1318 <= c :
  c <= 0x166C ?
  c <= 0x138F ?
  c <= 0x135F ?
  0x135F <= c :
  0x1380 <= c :
  c <= 0x13F4 ?
  0x13A0 <= c :
  0x1401 <= c :
  c <= 0x169A ?
  c <= 0x1676 ?
  0x166F <= c :
  0x1681 <= c :
  0x16A0 <= c :
  c <= 0x1770 ?
  c <= 0x1734 ?
  c <= 0x170C ?
  c <= 0x16F0 ?
  0x16EE <= c :
  0x1700 <= c :
  c <= 0x1714 ?
  0x170E <= c :
  0x1720 <= c :
  c <= 0x176C ?
  c <= 0x1753 ?
  0x1740 <= c :
  0x1760 <= c :
  0x176E <= c :
  c <= 0x17D7 ?
  c <= 0x17B3 ?
  c <= 0x1773 ?
  0x1772 <= c :
  0x1780 <= c :
  c <= 0x17D3 ?
  0x17B6 <= c :
  0x17D7 <= c :
  c <= 0x17E9 ?
  c <= 0x17DD ?
  0x17DC <= c :
  0x17E0 <= c :
  0x180B <= c :
  c <= 0x1B59 ?
  c <= 0x196D ?
  c <= 0x191C ?
  c <= 0x1877 ?
  c <= 0x1819 ?
  0x1810 <= c :
  0x1820 <= c :
  c <= 0x18A9 ?
  0x1880 <= c :
  0x1900 <= c :
  c <= 0x193B ?
  c <= 0x192B ?
  0x1920 <= c :
  0x1930 <= c :
  0x1946 <= c :
  c <= 0x19D9 ?
  c <= 0x19A9 ?
  c <= 0x1974 ?
  0x1970 <= c :
  0x1980 <= c :
  c <= 0x19C9 ?
  0x19B0 <= c :
  0x19D0 <= c :
  c <= 0x1B4B ?
  c <= 0x1A1B ?
  0x1A00 <= c :
  0x1B00 <= c :
  0x1B50 <= c :
  c <= 0x1F45 ?
  c <= 0x1EF9 ?
  c <= 0x1DCA ?
  c <= 0x1B73 ?
  0x1B6B <= c :
  0x1D00 <= c :
  c <= 0x1E9B ?
  0x1DFE <= c :
  0x1EA0 <= c :
  c <= 0x1F1D ?
  c <= 0x1F15 ?
  0x1F00 <= c :
  0x1F18 <= c :
  0x1F20 <= c :
  c <= 0x1F5B ?
  c <= 0x1F57 ?
  c <= 0x1F4D ?
  0x1F48 <= c :
  0x1F50 <= c :
  c <= 0x1F59 ?
  0x1F59 <= c :
  0x1F5B <= c :
  c <= 0x1F7D ?
  c <= 0x1F5D ?
  0x1F5D <= c :
  0x1F5F <= c :
  0x1F80 <= c :
  c <= 0x2149 ?
  c <= 0x20DC ?
  c <= 0x1FF4 ?
  c <= 0x1FCC ?
  c <= 0x1FBE ?
  c <= 0x1FBC ?
  0x1FB6 <= c :
  0x1FBE <= c :
  c <= 0x1FC4 ?
  0x1FC2 <= c :
  0x1FC6 <= c :
  c <= 0x1FDB ?
  c <= 0x1FD3 ?
  0x1FD0 <= c :
  0x1FD6 <= c :
  c <= 0x1FEC ?
  0x1FE0 <= c :
  0x1FF2 <= c :
  c <= 0x2071 ?
  c <= 0x2040 ?
  c <= 0x1FFC ?
  0x1FF6 <= c :
  0x203F <= c :
  c <= 0x2054 ?
  0x2054 <= c :
  0x2071 <= c :
  c <= 0x2094 ?
  c <= 0x207F ?
  0x207F <= c :
  0x2090 <= c :
  0x20D0 <= c :
  c <= 0x211D ?
  c <= 0x2107 ?
  c <= 0x20EF ?
  c <= 0x20E1 ?
  0x20E1 <= c :
  0x20E5 <= c :
  c <= 0x2102 ?
  0x2102 <= c :
  0x2107 <= c :
  c <= 0x2115 ?
  c <= 0x2113 ?
  0x210A <= c :
  0x2115 <= c :
  0x2119 <= c :
  c <= 0x212D ?
  c <= 0x2126 ?
  c <= 0x2124 ?
  0x2124 <= c :
  0x2126 <= c :
  c <= 0x2128 ?
  0x2128 <= c :
  0x212A <= c :
  c <= 0x213F ?
  c <= 0x2139 ?
  0x212F <= c :
  0x213C <= c :
  0x2145 <= c :
  c <= 0x2DB6 ?
  c <= 0x2CE4 ?
  c <= 0x2C5E ?
  c <= 0x2184 ?
  c <= 0x214E ?
  0x214E <= c :
  0x2160 <= c :
  c <= 0x2C2E ?
  0x2C00 <= c :
  0x2C30 <= c :
  c <= 0x2C77 ?
  c <= 0x2C6C ?
  0x2C60 <= c :
  0x2C74 <= c :
  0x2C80 <= c :
  c <= 0x2D96 ?
  c <= 0x2D65 ?
  c <= 0x2D25 ?
  0x2D00 <= c :
  0x2D30 <= c :
  c <= 0x2D6F ?
  0x2D6F <= c :
  0x2D80 <= c :
  c <= 0x2DAE ?
  c <= 0x2DA6 ?
  0x2DA0 <= c :
  0x2DA8 <= c :
  0x2DB0 <= c :
  c <= 0x302F ?
  c <= 0x2DD6 ?
  c <= 0x2DC6 ?
  c <= 0x2DBE ?
  0x2DB8 <= c :
  0x2DC0 <= c :
  c <= 0x2DCE ?
  0x2DC8 <= c :
  0x2DD0 <= c :
  c <= 0x3007 ?
  c <= 0x2DDE ?
  0x2DD8 <= c :
  0x3005 <= c :
  0x3021 <= c :
  c <= 0x309A ?
  c <= 0x303C ?
  c <= 0x3035 ?
  0x3031 <= c :
  0x3038 <= c :
  c <= 0x3096 ?
  0x3041 <= c :
  0x3099 <= c :
  c <= 0x30FA ?
  c <= 0x309F ?
  0x309D <= c :
  0x30A1 <= c :
  0x30FC <= c :
  c <= 0x1049D ?
  c <= 0xFE23 ?
  c <= 0xFB06 ?
  c <= 0xA71A ?
  c <= 0x31FF ?
  c <= 0x318E ?
  c <= 0x312C ?
  0x3105 <= c :
  0x3131 <= c :
  c <= 0x31B7 ?
  0x31A0 <= c :
  0x31F0 <= c :
  c <= 0x9FBB ?
  c <= 0x4DB5 ?
  0x3400 <= c :
  0x4E00 <= c :
  c <= 0xA48C ?
  0xA000 <= c :
  0xA717 <= c :
  c <= 0xFA2D ?
  c <= 0xA873 ?
  c <= 0xA827 ?
  0xA800 <= c :
  0xA840 <= c :
  c <= 0xD7A3 ?
  0xAC00 <= c :
  0xF900 <= c :
  c <= 0xFAD9 ?
  c <= 0xFA6A ?
  0xFA30 <= c :
  0xFA70 <= c :
  0xFB00 <= c :
  c <= 0xFB44 ?
  c <= 0xFB3C ?
  c <= 0xFB28 ?
  c <= 0xFB17 ?
  0xFB13 <= c :
  0xFB1D <= c :
  c <= 0xFB36 ?
  0xFB2A <= c :
  0xFB38 <= c :
  c <= 0xFB41 ?
  c <= 0xFB3E ?
  0xFB3E <= c :
  0xFB40 <= c :
  0xFB43 <= c :
  c <= 0xFDC7 ?
  c <= 0xFD3D ?
  c <= 0xFBB1 ?
  0xFB46 <= c :
  0xFBD3 <= c :
  c <= 0xFD8F ?
  0xFD50 <= c :
  0xFD92 <= c :
  c <= 0xFE0F ?
  c <= 0xFDFB ?
  0xFDF0 <= c :
  0xFE00 <= c :
  0xFE20 <= c :
  c <= 0x1000B ?
  c <= 0xFF3F ?
  c <= 0xFEFC ?
  c <= 0xFE4F ?
  c <= 0xFE34 ?
  0xFE33 <= c :
  0xFE4D <= c :
  c <= 0xFE74 ?
  0xFE70 <= c :
  0xFE76 <= c :
  c <= 0xFF3A ?
  c <= 0xFF19 ?
  0xFF10 <= c :
  0xFF21 <= c :
  0xFF3F <= c :
  c <= 0xFFCF ?
  c <= 0xFFBE ?
  c <= 0xFF5A ?
  0xFF41 <= c :
  0xFF66 <= c :
  c <= 0xFFC7 ?
  0xFFC2 <= c :
  0xFFCA <= c :
  c <= 0xFFDC ?
  c <= 0xFFD7 ?
  0xFFD2 <= c :
  0xFFDA <= c :
  0x10000 <= c :
  c <= 0x10174 ?
  c <= 0x1004D ?
  c <= 0x1003A ?
  c <= 0x10026 ?
  0x1000D <= c :
  0x10028 <= c :
  c <= 0x1003D ?
  0x1003C <= c :
  0x1003F <= c :
  c <= 0x100FA ?
  c <= 0x1005D ?
  0x10050 <= c :
  0x10080 <= c :
  0x10140 <= c :
  c <= 0x103C3 ?
  c <= 0x1034A ?
  c <= 0x1031E ?
  0x10300 <= c :
  0x10330 <= c :
  c <= 0x1039D ?
  0x10380 <= c :
  0x103A0 <= c :
  c <= 0x103D5 ?
  c <= 0x103CF ?
  0x103C8 <= c :
  0x103D1 <= c :
  0x10400 <= c :
  c <= 0x1D4AC ?
  c <= 0x10A3F ?
  c <= 0x10915 ?
  c <= 0x10835 ?
  c <= 0x10805 ?
  c <= 0x104A9 ?
  0x104A0 <= c :
  0x10800 <= c :
  c <= 0x10808 ?
  0x10808 <= c :
  0x1080A <= c :
  c <= 0x1083C ?
  c <= 0x10838 ?
  0x10837 <= c :
  0x1083C <= c :
  c <= 0x1083F ?
  0x1083F <= c :
  0x10900 <= c :
  c <= 0x10A17 ?
  c <= 0x10A06 ?
  c <= 0x10A03 ?
  0x10A00 <= c :
  0x10A05 <= c :
  c <= 0x10A13 ?
  0x10A0C <= c :
  0x10A15 <= c :
  c <= 0x10A3A ?
  c <= 0x10A33 ?
  0x10A19 <= c :
  0x10A38 <= c :
  0x10A3F <= c :
  c <= 0x1D1AD ?
  c <= 0x1D172 ?
  c <= 0x12462 ?
  c <= 0x1236E ?
  0x12000 <= c :
  0x12400 <= c :
  c <= 0x1D169 ?
  0x1D165 <= c :
  0x1D16D <= c :
  c <= 0x1D18B ?
  c <= 0x1D182 ?
  0x1D17B <= c :
  0x1D185 <= c :
  0x1D1AA <= c :
  c <= 0x1D49F ?
  c <= 0x1D454 ?
  c <= 0x1D244 ?
  0x1D242 <= c :
  0x1D400 <= c :
  c <= 0x1D49C ?
  0x1D456 <= c :
  0x1D49E <= c :
  c <= 0x1D4A6 ?
  c <= 0x1D4A2 ?
  0x1D4A2 <= c :
  0x1D4A5 <= c :
  0x1D4A9 <= c :
  c <= 0x1D6C0 ?
  c <= 0x1D51C ?
  c <= 0x1D505 ?
  c <= 0x1D4BB ?
  c <= 0x1D4B9 ?
  0x1D4AE <= c :
  0x1D4BB <= c :
  c <= 0x1D4C3 ?
  0x1D4BD <= c :
  0x1D4C5 <= c :
  c <= 0x1D514 ?
  c <= 0x1D50A ?
  0x1D507 <= c :
  0x1D50D <= c :
  0x1D516 <= c :
  c <= 0x1D546 ?
  c <= 0x1D53E ?
  c <= 0x1D539 ?
  0x1D51E <= c :
  0x1D53B <= c :
  c <= 0x1D544 ?
  0x1D540 <= c :
  0x1D546 <= c :
  c <= 0x1D6A5 ?
  c <= 0x1D550 ?
  0x1D54A <= c :
  0x1D552 <= c :
  0x1D6A8 <= c :
  c <= 0x1D788 ?
  c <= 0x1D734 ?
  c <= 0x1D6FA ?
  c <= 0x1D6DA ?
  0x1D6C2 <= c :
  0x1D6DC <= c :
  c <= 0x1D714 ?
  0x1D6FC <= c :
  0x1D716 <= c :
  c <= 0x1D76E ?
  c <= 0x1D74E ?
  0x1D736 <= c :
  0x1D750 <= c :
  0x1D770 <= c :
  c <= 0x1D7FF ?
  c <= 0x1D7C2 ?
  c <= 0x1D7A8 ?
  0x1D78A <= c :
  0x1D7AA <= c :
  c <= 0x1D7CB ?
  0x1D7C4 <= c :
  0x1D7CE <= c :
  c <= 0x2FA1D ?
  c <= 0x2A6D6 ?
  0x20000 <= c :
  0x2F800 <= c :
  0xE0100 <= c && c <= 0xE01EF;
  // #/generated#
}


          return {
              isDigit: isDigit, isIdentifierStart: isIdentifierStart, isHexDigit: isHexDigit, isAlpha: isAlpha, isSpace: isSpace, isLineTerminator: isLineTerminator, isFormatChar: isFormatChar, isIdentifierPart: isIdentifierPart
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.isDigit = isDigit;
  this.Concurrent.Thread.Compiler.isIdentifierStart = isIdentifierStart;
  this.Concurrent.Thread.Compiler.isHexDigit = isHexDigit;
  this.Concurrent.Thread.Compiler.isAlpha = isAlpha;
  this.Concurrent.Thread.Compiler.isSpace = isSpace;
  this.Concurrent.Thread.Compiler.isLineTerminator = isLineTerminator;
  this.Concurrent.Thread.Compiler.isFormatChar = isFormatChar;
  this.Concurrent.Thread.Compiler.isIdentifierPart = isIdentifierPart;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Http || (typeof this.Concurrent.Thread.Http != 'object' && typeof this.Concurrent.Thread.Http != 'function') ) this.Concurrent.Thread.Http = new Object();
  if ( this.Concurrent.Thread.Http.send === undefined ) this.Concurrent.Thread.Http.send = undefined;
  if ( this.Concurrent.Thread.Http.get === undefined ) this.Concurrent.Thread.Http.get = undefined;
  if ( this.Concurrent.Thread.Http.post === undefined ) this.Concurrent.Thread.Http.post = undefined;
with ( function(){
with ( Concurrent.Thread.Http ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Http';




var createXMLHttpRequest;  // Set up according to environment.
try {
  new XMLHttpRequest();
  createXMLHttpRequest = function ( ) {
      return new XMLHttpRequest();
  };
} catch ( e ) {
  try {
      // MSXML3 or later
      new ActiveXObject("Msxml2.XMLHTTP");
      createXMLHttpRequest = function ( ) {
          return new ActiveXObject("Msxml2.XMLHTTP");
      };
  } catch ( e ) {
      try {
          // MSXML up to 2
          new ActiveXObject("Microsoft.XMLHTTP");
          createXMLHttpRequest = function ( ) {
              return new ActiveXObject("Microsoft.XMLHTTP");
          };
      } catch ( e ) {
          throw new Error(NAMESPACE + ": can't load XMLHttpRequest object");
      }
  }
}



function send ( method, url, body, headers ) {
  throw new Error(NAMESPACE + ".send is unusable in non-compiled function");
}

var LoadedException = {};

send.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  var method=$args[0], url=$args[1], body=$args[2], headers=$args[3];
  if ( !headers || !(headers instanceof Array) ) headers = [];
  var req = createXMLHttpRequest();
  req.open(method, url, true);
  for ( var i=0;  i < headers.length;  i+=2 ) {
      req.setRequestHeader(headers[i], headers[i+1]);
  }
  var self = Concurrent.Thread.self();
  var loaded    = false;
  var cache_hit = true;
  req.onreadystatechange = function ( ) {
      if ( req.readyState == 4 ) {
          loaded = true;
          if ( !cache_hit ) self.notify(LoadedException);
      }
  };
  req.send(body);  // Firefox occasionally causes "onload" event here. Maybe, it occurs in case of cache-hit.
  cache_hit = false;
  if ( loaded ) {
      return {
          continuation: $cont,
          ret_val     : req,
          timeout     : undefined
      };
  } else {
      var ex_handler = {
          procedure: function ( e ) {
              if ( e === LoadedException ) {
                  return {
                      continuation: $cont,
                      ret_val     : req,
                      timeout     : undefined
                  };
              } else {
                  try{ req.abort(); }catch(_){}  // IE less than 7 does not support "abort".
                  return {
                      continuation: $cont.exception,
                      ret_val     : e,
                      timeout     : undefined
                  };
              }
          },
          this_val : null
      };
      ex_handler.exception = ex_handler;  // Cyclic reference assures to abort request.
      return {
          timeout     : -1,
          continuation: {
              procedure: null,
              this_val : null,
              exception: ex_handler
          }
      };
  }
};



function get ( url, headers ) {
  throw new Error(NAMESPACE + ".get is unusable in non-compiled function");
}

get.$Concurrent_Thread_compiled = function ($this, $args, $cont) {
  return send.$Concurrent_Thread_compiled(
      null,
      ["GET", $args[0], $args[1], null],
      $cont
  );
}



function post ( url, body, headers ) {
  throw new Error(NAMESPACE + ".post is unusable in non-compiled function");
}

post.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  var url=$args[0], body=$args[1], headers=$args[2];
  if ( typeof body == "object" ) {
      var vals = [];
      for ( var i in body ) {
          if ( body.hasOwnProperty(i) ) {
              vals.push( encodeURIComponent(i) + "=" + encodeURIComponent(body[i]) );
          }
      }
      body = vals.join("&");
  }
  if ( !headers || !(headers instanceof Array) ) headers = [];
  var content_type_exists = false;
  for ( var i=0;  i < headers.length;  i+=2 ) {
      if ( String(headers[i]).match(/^Content-type$/i) ) {
          content_type_exists = true;
          break;
      }
  }
  if ( !content_type_exists ) {
      headers = headers.concat("Content-type", "application/x-www-form-urlencoded");
  }
  return send.$Concurrent_Thread_compiled(
      null,
      ["POST", url, body, headers],
      $cont
  );
};

          return {
              send: send, post: post, get: get
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Http.send = send;
  this.Concurrent.Thread.Http.post = post;
  this.Concurrent.Thread.Http.get = get;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( this.Concurrent.Thread.Mutex === undefined ) this.Concurrent.Thread.Mutex = undefined;
with ( function(){
with ( Data ) {
with ( Data.Error ) {
with ( Concurrent ) {
with ( Concurrent.Thread ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread';














function Mutex ( ) {
  this._acquiring = null;
  this._waiting   = new LinkedList();
}

var proto = Mutex.prototype;


proto.isAcquirable = function ( ) {
  return !this._acquiring  &&  this._waiting.isEmpty();
};


proto.acquire = function ( ) {
  throw new Error("can't `acquire' in non-converted function");
};

proto.acquire.$Concurrent_Thread_compiled = function ( $this, $args, $cont ) {
  if ( $this.isAcquirable() ) {
      $this._acquiring = Thread.self();
      return {
          continuation: $cont ,
          ret_val     : void 0,
          timeout     : void 0
      };
  } else {
      $this._waiting.push(Thread.self());
      var callee = arguments.callee;
      return {
          continuation: {
              procedure: null,
              this_val : null,
              exception: {
                  procedure: function( e ){
                      if ( e === releasedException ) {
                          if ( $this._waiting.shift() !== Thread.self() ) {
                              return {
                                  continuation: $cont.exception,
                                  ret_val     : new IllegalStateError("unknown state (maybe bug)"),
                                  timeout     : void 0
                              };
                          }
                          $this._acquiring = Thread.self();
                          return {
                              continuation: $cont,
                              ret_val     : void 0,
                              timeout     : void 0
                          };
                      } else {
                          $this._waiting.head().find(function( it ){
                              return it === Thread.self();
                          }).remove();
                          return {
                              continuation: $cont.exception,
                              ret_val     : e,
                              timeout     : void 0
                          };
                      }
                  },
                  this_val : null,
                  exception: $cont.exception
              }
          },
          ret_val: void 0,
          timeout: -1
      };
  }
};


proto.release = function ( ) {
  if ( !this._acquiring ) {
      throw new IllegalStateError("mutex is not locked");
  }
  if ( this._acquiring !== Thread.self() ) {
      throw new IllegalStateError("mutex can be released only by the thread locking it");
  }
  this._acquiring = null;
  if ( !this._waiting.isEmpty() ) {
      this._waiting.head().value().notify(releasedException);
  }
};


var releasedException = {};

          return {
              Mutex: Mutex
          };
      }();
  }
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.Mutex = Mutex;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.Expression === undefined ) this.Concurrent.Thread.Compiler.Expression = undefined;
  if ( this.Concurrent.Thread.Compiler.UnaryExpression === undefined ) this.Concurrent.Thread.Compiler.UnaryExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BinaryExpression === undefined ) this.Concurrent.Thread.Compiler.BinaryExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.ThisExpression === undefined ) this.Concurrent.Thread.Compiler.ThisExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.Identifier === undefined ) this.Concurrent.Thread.Compiler.Identifier = undefined;
  if ( this.Concurrent.Thread.Compiler.Literal === undefined ) this.Concurrent.Thread.Compiler.Literal = undefined;
  if ( this.Concurrent.Thread.Compiler.NumberLiteral === undefined ) this.Concurrent.Thread.Compiler.NumberLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.StringLiteral === undefined ) this.Concurrent.Thread.Compiler.StringLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.RegExpLiteral === undefined ) this.Concurrent.Thread.Compiler.RegExpLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.NullLiteral === undefined ) this.Concurrent.Thread.Compiler.NullLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.BooleanLiteral === undefined ) this.Concurrent.Thread.Compiler.BooleanLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.TrueLiteral === undefined ) this.Concurrent.Thread.Compiler.TrueLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.FalseLiteral === undefined ) this.Concurrent.Thread.Compiler.FalseLiteral = undefined;
  if ( this.Concurrent.Thread.Compiler.ArrayInitializer === undefined ) this.Concurrent.Thread.Compiler.ArrayInitializer = undefined;
  if ( this.Concurrent.Thread.Compiler.Elision === undefined ) this.Concurrent.Thread.Compiler.Elision = undefined;
  if ( this.Concurrent.Thread.Compiler.ObjectInitializer === undefined ) this.Concurrent.Thread.Compiler.ObjectInitializer = undefined;
  if ( this.Concurrent.Thread.Compiler.FunctionExpression === undefined ) this.Concurrent.Thread.Compiler.FunctionExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.DotAccessor === undefined ) this.Concurrent.Thread.Compiler.DotAccessor = undefined;
  if ( this.Concurrent.Thread.Compiler.BracketAccessor === undefined ) this.Concurrent.Thread.Compiler.BracketAccessor = undefined;
  if ( this.Concurrent.Thread.Compiler.NewExpression === undefined ) this.Concurrent.Thread.Compiler.NewExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.CallExpression === undefined ) this.Concurrent.Thread.Compiler.CallExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.PostIncExpression === undefined ) this.Concurrent.Thread.Compiler.PostIncExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.PostDecExpression === undefined ) this.Concurrent.Thread.Compiler.PostDecExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.PreIncExpression === undefined ) this.Concurrent.Thread.Compiler.PreIncExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.PreDecExpression === undefined ) this.Concurrent.Thread.Compiler.PreDecExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.DeleteExpression === undefined ) this.Concurrent.Thread.Compiler.DeleteExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.VoidExpression === undefined ) this.Concurrent.Thread.Compiler.VoidExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.TypeofExpression === undefined ) this.Concurrent.Thread.Compiler.TypeofExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.PosExpression === undefined ) this.Concurrent.Thread.Compiler.PosExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.NegExpression === undefined ) this.Concurrent.Thread.Compiler.NegExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitNotExpression === undefined ) this.Concurrent.Thread.Compiler.BitNotExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.NotExpression === undefined ) this.Concurrent.Thread.Compiler.NotExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.MulExpression === undefined ) this.Concurrent.Thread.Compiler.MulExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.DivExpression === undefined ) this.Concurrent.Thread.Compiler.DivExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.ModExpression === undefined ) this.Concurrent.Thread.Compiler.ModExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.AddExpression === undefined ) this.Concurrent.Thread.Compiler.AddExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.SubExpression === undefined ) this.Concurrent.Thread.Compiler.SubExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.LShiftExpression === undefined ) this.Concurrent.Thread.Compiler.LShiftExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.RShiftExpression === undefined ) this.Concurrent.Thread.Compiler.RShiftExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.URShiftExpression === undefined ) this.Concurrent.Thread.Compiler.URShiftExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.LessThanExpression === undefined ) this.Concurrent.Thread.Compiler.LessThanExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.GreaterThanExpression === undefined ) this.Concurrent.Thread.Compiler.GreaterThanExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.LessEqualExpression === undefined ) this.Concurrent.Thread.Compiler.LessEqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.GreaterEqualExpression === undefined ) this.Concurrent.Thread.Compiler.GreaterEqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.InstanceofExpression === undefined ) this.Concurrent.Thread.Compiler.InstanceofExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.InExpression === undefined ) this.Concurrent.Thread.Compiler.InExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.EqualExpression === undefined ) this.Concurrent.Thread.Compiler.EqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.NotEqualExpression === undefined ) this.Concurrent.Thread.Compiler.NotEqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.StrictEqualExpression === undefined ) this.Concurrent.Thread.Compiler.StrictEqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.StrictNotEqualExpression === undefined ) this.Concurrent.Thread.Compiler.StrictNotEqualExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitAndExpression === undefined ) this.Concurrent.Thread.Compiler.BitAndExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitXorExpression === undefined ) this.Concurrent.Thread.Compiler.BitXorExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitOrExpression === undefined ) this.Concurrent.Thread.Compiler.BitOrExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.AndExpression === undefined ) this.Concurrent.Thread.Compiler.AndExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.OrExpression === undefined ) this.Concurrent.Thread.Compiler.OrExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.ConditionalExpression === undefined ) this.Concurrent.Thread.Compiler.ConditionalExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.AssignExpression === undefined ) this.Concurrent.Thread.Compiler.AssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.SimpleAssignExpression === undefined ) this.Concurrent.Thread.Compiler.SimpleAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.MulAssignExpression === undefined ) this.Concurrent.Thread.Compiler.MulAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.DivAssignExpression === undefined ) this.Concurrent.Thread.Compiler.DivAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.ModAssignExpression === undefined ) this.Concurrent.Thread.Compiler.ModAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.AddAssignExpression === undefined ) this.Concurrent.Thread.Compiler.AddAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.SubAssignExpression === undefined ) this.Concurrent.Thread.Compiler.SubAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.LShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.LShiftAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.RShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.RShiftAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.URShiftAssignExpression === undefined ) this.Concurrent.Thread.Compiler.URShiftAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitAndAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitAndAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitXorAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitXorAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.BitOrAssignExpression === undefined ) this.Concurrent.Thread.Compiler.BitOrAssignExpression = undefined;
  if ( this.Concurrent.Thread.Compiler.CommaExpression === undefined ) this.Concurrent.Thread.Compiler.CommaExpression = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';










function Expression ( ) {
  // This is kind of abstract class.
}

var proto = Expression.prototype;

proto.toString = function ( ) {
  Kit.codeBug("Unimplemented method `toString' of class: " + this.constructor);
};

proto.containsFunctionCall = function ( ) {
  Kit.codeBug("Unimplemented method `containsFunctionCall' of class: " + this.constructor);
};

proto.hasSideEffect = function ( ) {
  Kit.codeBug("Unimplemented method `hasSideEffect' of class: " + this.constructor);
};

proto.hasLvalue = function ( ) {
  return false;
};



function UnaryExpression ( e ) {
  // This is kind of abstract class and should not be instantiated directly.
  // It just provides default implementations of methods and constructor.
  this.exp = e;  // Expression
}

var proto = UnaryExpression.prototype = new Expression();
proto.constructor = UnaryExpression;

proto.containsFunctionCall = function ( ) {
  return this.exp.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
  return this.exp.hasSideEffect();
};



function BinaryExpression ( l, r ) {
  // This is kind of abstract class and should not be instantiated directly.
  // It just provides default implementations of methods and constructor.
  this.left  = l;  // Expression
  this.right = r;  // Expression
}

var proto = BinaryExpression.prototype = new Expression();
proto.constructor = BinaryExpression;

proto.containsFunctionCall = function ( ) {
  return this.left.containsFunctionCall() || this.right.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
  return this.left.hasSideEfect() || this.right.hasSideEffect();
};



function ThisExpression ( ) {
  return THIS_EXPRESSION;  // Reuse object.
}

var proto = ThisExpression.prototype = new Expression();
proto.constructor = ThisExpression;

proto.toString = function ( ) {
  return "this";
};

proto.containsFunctionCall = function ( ) {
  return false;
};

proto.hasSideEffect = function ( ) {
  return false;
};

function temp ( ) { }
temp.prototype = ThisExpression.prototype;
var THIS_EXPRESSION = new temp();



function Identifier ( s ) {
  this.string = String(s);
  this.value  = eval('"' + this.string + '"');
}

var proto = Identifier.prototype = new Expression();
proto.constructor = Identifier;

proto.toString = function ( ) {
  return this.string;
};

proto.valueOf = function ( ) {
  return this.value;
};

proto.hasLvalue = function ( ) {
  return true;
};

proto.containsFunctionCall = function ( ) {
  return false;
};

proto.hasSideEffect = function ( ) {
  return false;
};



function Literal ( s ) {
  this.string = String(s);
  this.value  = eval(this.string);
}

var proto = Literal.prototype = new Expression();
proto.constructor = Literal;

proto.toString = function ( ) {
  return this.string;
};

proto.valueOf = function ( ) {
  return this.value;
};

proto.containsFunctionCall = function ( ) {
  return false;
};

proto.hasSideEffect = function ( ) {
  return false;
};



function NumberLiteral ( s ) {
  Literal.apply(this, arguments);
}

var proto = NumberLiteral.prototype = new Literal();
proto.constructor = NumberLiteral;



function StringLiteral ( s ) {
  Literal.apply(this, arguments);
}

var proto = StringLiteral.prototype = new Literal();
proto.constructor = StringLiteral;



function RegExpLiteral ( s ) {
  Literal.apply(this, arguments);
}

var proto = RegExpLiteral.prototype = new Literal();
proto.constructor = RegExpLiteral;



function NullLiteral ( ) {
  return NULL_LITERAL;  // Reuse object.
}

var proto = NullLiteral.prototype = new Literal();
proto.constructor = NullLiteral;

proto.string = "null";
proto.vakue  = null;

proto.toString = function ( ) {
  return "null";
};

proto.valueOf = function ( ) {
  return null;
};

function temp ( ) { }
temp.prototype = NullLiteral.prototype;
var NULL_LITERAL = new temp();



function BooleanLiteral ( ) { }

var proto = BooleanLiteral.prototype = new Literal();
proto.constructor = BooleanLiteral;



function TrueLiteral ( ) {
  return TRUE_LITERAL;  // Reuse object.
}

var proto = TrueLiteral.prototype = new BooleanLiteral();
proto.constructor = TrueLiteral;

proto.string = "true";
proto.vakue  = true;

proto.toString = function ( ) {
  return "true";
};

proto.valueOf = function ( ) {
  return true;
};

function temp ( ) { }
temp.prototype = TrueLiteral.prototype;
var TRUE_LITERAL = new temp();



function FalseLiteral ( ) {
  return FALSE_LITERAL;  // Reuse object.
}

var proto = FalseLiteral.prototype = new BooleanLiteral();
proto.constructor = FalseLiteral;

proto.string = "false";
proto.vakue  = false;

proto.toString = function ( ) {
  return "false";
};

proto.valueOf = function ( ) {
  return false;
};

function temp ( ) { }
temp.prototype = FalseLiteral.prototype;
var FALSE_LITERAL = new temp();



function ArrayInitializer ( elems ) {
  this.elems = elems;  // array of Expression
}

var proto = ArrayInitializer.prototype = new Expression();
proto.constructor = ArrayInitializer;

proto.toString = function ( ) {
  return "[" + this.elems.join(", ") + "]";
};

proto.containsFunctionCall = function ( ) {
  for ( var i=0;  i < this.elems.length;  i++ ) {
      if ( this.elems[i].containsFunctionCall() ) return true;
  }
  return false;
};

proto.hasSideEfect = function ( ) {
  for ( var i=0;  i < this.elems.length;  i++ ) {
      if ( this.elems[i].hasSideEffect() ) return true;
  }
  return false;
};



function Elision ( ) { }

var proto = Elision.prototype = new Expression();
proto.constructor = Elision;

proto.toString = function ( ) {
  return "";
};

proto.containsFunctionCall = function ( ) {
  return false;
};

proto.hasSideEffect = function ( ) {
  return false;
};



function ObjectInitializer ( v ) {
  this.pairs = v;  // array of {prop: Identifier or Literal,  exp: Expression}
}

var proto = ObjectInitializer.prototype = new Expression();
proto.constructor = ObjectInitializer;

proto.toString = function ( ) {
  var buf = [];
  for ( var i=0;  i < this.pairs.length;  i++ ) {
      buf.push( String(this.pairs[i].prop) + ":" + String(this.pairs[i].exp) );
  }
  return "{" + buf.join(", ") + "}";
};

proto.containsFunctionCall = function ( ) {
  for ( var i=0;  i < this.pairs.length;  i++ ) {
      if ( this.pairs[i].exp.containsFunctionCall() ) return true;
  }
  return false;
};

proto.hasSideEffect = function ( ) {
  for ( var i=0;  i < this.pairs.length;  i++ ) {
      if ( this.pairs[i].exp.hasSideEffect() ) return true;
  }
  return false;
};



function FunctionExpression ( name, params, body ) {
  this.name   = name;    // Identifier or null
  this.params = params;  // array of Identifier
  this.body   = body;    // cons-list of Statement
}

var proto = FunctionExpression.prototype = new Expression();
proto.constructor = FunctionExpression;

proto.toString = function ( ) {
  var buf = ["(function "];
  if ( this.name ) buf.push(this.name);
  buf.push( "(", this.params.join(", "), ") {\n");
  this.body.forEach(function( it ){
      buf.push(it, "\n");
  });
  buf.push("})");
  return buf.join("");
};

proto.containsFunctionCall = function ( ) {
  return false;
};

proto.hasSideEffect = function ( ) {
  return false;
};



function DotAccessor ( base, prop ) {
  this.base = base;  // Expression
  this.prop = prop;  // Identifier
}

var proto = DotAccessor.prototype = new Expression();
proto.constructor = DotAccessor;

proto.toString = function ( ) {
  return String(this.base) + "." + String(this.prop);
};

proto.hasLvalue = function ( ) {
  return true;
};

proto.containsFunctionCall = function ( ) {
  return this.base.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
  return this.base.hasSideEffect();
};



function BracketAccessor ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = BracketAccessor.prototype = new BinaryExpression();
proto.constructor = BracketAccessor;

proto.toString = function ( ) {
  return [ this.left, "[", this.right, "]" ].join("");
};

proto.hasLvalue = function ( ) {
  return true;
};



function NewExpression ( func, args ) {
  this.func = func;  // Expression
  this.args = args;  // array of Expression
}

var proto = NewExpression.prototype = new Expression();
proto.constructor = NewExpression;

proto.toString = function ( ) {
  return [ "new ", this.func, "(", this.args.join(", "), ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
  return true;
};

proto.hasSideEffect = function ( ) {
  return true;
};



function CallExpression ( func, args ) {
  this.func = func;  // Expression
  this.args = args;  // array of Expression
}

var proto = CallExpression.prototype = new Expression();
proto.constructor = CallExpression;

proto.toString = function ( ) {
  return [ this.func, "(", this.args.join(", "), ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
  return true;
};

proto.hasSideEffect = function ( ) {
  return true;
};



function PostIncExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = PostIncExpression.prototype = new UnaryExpression();
proto.constructor = PostIncExpression;

proto.toString = function ( ) {
  return String(this.exp) + "++";
};

proto.hasSideEffect = function ( ) {
  return true;
};



function PostDecExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = PostDecExpression.prototype = new UnaryExpression();
proto.constructor = PostDecExpression;

proto.toString = function ( ) {
  return String(this.exp) + "--";
};

proto.hasSideEffect = function ( ) {
  return true;
};



function PreIncExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = PreIncExpression.prototype = new UnaryExpression();
proto.constructor = PreIncExpression;

proto.toString = function ( ) {
  return "++" + String(this.exp);
};

proto.hasSideEffect = function ( ) {
  return true;
};



function PreDecExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = PreDecExpression.prototype = new UnaryExpression();
proto.constructor = PreDecExpression;

proto.toString = function ( ) {
  return "--" + String(this.exp);
};

proto.hasSideEffect = function ( ) {
  return true;
};



function DeleteExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = DeleteExpression.prototype = new UnaryExpression();
proto.constructor = DeleteExpression;

proto.toString = function ( ) {
  return "delete " + String(this.exp);
};

proto.hasSideEffect = function ( ) {
  return true;
};



function VoidExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = VoidExpression.prototype = new UnaryExpression();
proto.constructor = VoidExpression;

proto.toString = function ( ) {
  return "void " + String(this.exp);
};



function TypeofExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = TypeofExpression.prototype = new UnaryExpression();
proto.constructor = TypeofExpression;

proto.toString = function ( ) {
  return "typeof " + String(this.exp);
};



function PosExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = PosExpression.prototype = new UnaryExpression();
proto.constructor = PosExpression;

proto.toString = function ( ) {
  return "+ " + String(this.exp);
};



function NegExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = NegExpression.prototype = new UnaryExpression();
proto.constructor = NegExpression;

proto.toString = function ( ) {
  return "- " + String(this.exp);
};



function BitNotExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = BitNotExpression.prototype = new UnaryExpression();
proto.constructor = BitNotExpression;

proto.toString = function ( ) {
  return "~" + String(this.exp);
};



function NotExpression ( e ) {
  UnaryExpression.apply(this, arguments);
}

var proto = NotExpression.prototype = new UnaryExpression();
proto.constructor = NotExpression;

proto.toString = function ( ) {
  return "!" + String(this.exp);
};



function MulExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = MulExpression.prototype = new BinaryExpression();
proto.constructor = MulExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " * ", this.right, ")" ].join("");
};



function DivExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = DivExpression.prototype = new BinaryExpression();
proto.constructor = DivExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " / ", this.right, ")" ].join("");
};



function ModExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = ModExpression.prototype = new BinaryExpression();
proto.constructor = ModExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " % ", this.right, ")" ].join("");
};



function AddExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = AddExpression.prototype = new BinaryExpression();
proto.constructor = AddExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " + ", this.right, ")" ].join("");
};



function SubExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = SubExpression.prototype = new BinaryExpression();
proto.constructor = SubExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " - ", this.right, ")" ].join("");
};



function LShiftExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = LShiftExpression.prototype = new BinaryExpression();
proto.constructor = LShiftExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " << ", this.right, ")" ].join("");
};



function RShiftExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = RShiftExpression.prototype = new BinaryExpression();
proto.constructor = RShiftExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " >> ", this.right, ")" ].join("");
};



function URShiftExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = URShiftExpression.prototype = new BinaryExpression();
proto.constructor = URShiftExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " >>> ", this.right, ")" ].join("");
};



function LessThanExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = LessThanExpression.prototype = new BinaryExpression();
proto.constructor = LessThanExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " < ", this.right, ")" ].join("");
};



function GreaterThanExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = GreaterThanExpression.prototype = new BinaryExpression();
proto.constructor = GreaterThanExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " > ", this.right, ")" ].join("");
};



function LessEqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = LessEqualExpression.prototype = new BinaryExpression();
proto.constructor = LessEqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " <= ", this.right, ")" ].join("");
};



function GreaterEqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = GreaterEqualExpression.prototype = new BinaryExpression();
proto.constructor = GreaterEqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " >= ", this.right, ")" ].join("");
};



function InstanceofExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = InstanceofExpression.prototype = new BinaryExpression();
proto.constructor = InstanceofExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " instanceof ", this.right, ")" ].join("");
};



function InExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = InExpression.prototype = new BinaryExpression();
proto.constructor = InExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " in ", this.right, ")" ].join("");
};



function EqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = EqualExpression.prototype = new BinaryExpression();
proto.constructor = EqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " == ", this.right, ")" ].join("");
};



function NotEqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = NotEqualExpression.prototype = new BinaryExpression();
proto.constructor = NotEqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " != ", this.right, ")" ].join("");
};



function StrictEqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = StrictEqualExpression.prototype = new BinaryExpression();
proto.constructor = StrictEqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " === ", this.right, ")" ].join("");
};



function StrictNotEqualExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = StrictNotEqualExpression.prototype = new BinaryExpression();
proto.constructor = StrictNotEqualExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " !== ", this.right, ")" ].join("");
};



function BitAndExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = BitAndExpression.prototype = new BinaryExpression();
proto.constructor = BitAndExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " & ", this.right, ")" ].join("");
};



function BitXorExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = BitXorExpression.prototype = new BinaryExpression();
proto.constructor = BitXorExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " ^ ", this.right, ")" ].join("");
};



function BitOrExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = BitOrExpression.prototype = new BinaryExpression();
proto.constructor = BitOrExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " | ", this.right, ")" ].join("");
};



function AndExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = AndExpression.prototype = new BinaryExpression();
proto.constructor = AndExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " && ", this.right, ")" ].join("");
};



function OrExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = OrExpression.prototype = new BinaryExpression();
proto.constructor = OrExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " || ", this.right, ")" ].join("");
};



function ConditionalExpression ( c, t, f ) {
  this.cond = c;  // Expression
  this.texp = t;  // Expression
  this.fexp = f;  // Expression
}

var proto = ConditionalExpression.prototype = new Expression();
proto.constructor = ConditionalExpression;

proto.toString = function ( ) {
  return [ "(", this.cond, " ? ", this.texp, " : ", this.fexp, ")" ].join("");
};

proto.containsFunctionCall = function ( ) {
  return this.cond.containsFunctionCall()
      || this.texp.containsFunctionCall()
      || this.fexp.containsFunctionCall();
};

proto.hasSideEffect = function ( ) {
  return this.cond.hasSideEffect()
      || this.texp.hasSideEffect()
      || this.fexp.hasSideEffect();
};



function AssignExpression ( left, right ) {
  // This is kind of interface. It just represents a set of classes.
  BinaryExpression.apply(this, arguments);
}

var proto = AssignExpression.prototype = new BinaryExpression();
proto.constructor = AssignExpression;

proto.hasSideEffect = function ( ) {
  return true;
};



function SimpleAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = SimpleAssignExpression.prototype = new AssignExpression();
proto.constructor = SimpleAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " = ", this.right, ")" ].join("");
};



function MulAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = MulAssignExpression.prototype = new AssignExpression();
proto.constructor = MulAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " *= ", this.right, ")" ].join("");
};



function DivAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = DivAssignExpression.prototype = new AssignExpression();
proto.constructor = DivAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " /= ", this.right, ")" ].join("");
};



function ModAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = ModAssignExpression.prototype = new AssignExpression();
proto.constructor = ModAssignExpression;

proto.toString = function ( ) {
  return [ "(",  this.left, " %= ", this.right, ")" ].join("");
};



function AddAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = AddAssignExpression.prototype = new AssignExpression();
proto.constructor = AddAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " += ", this.right, ")" ].join("");
};



function SubAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = SubAssignExpression.prototype = new AssignExpression();
proto.constructor = SubAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " -= ", this.right, ")" ].join("");
};



function LShiftAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = LShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = LShiftAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " <<= ", this.right, ")" ].join("");
};



function RShiftAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = RShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = RShiftAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " >>= ", this.right, ")" ].join("");
};



function URShiftAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = URShiftAssignExpression.prototype = new AssignExpression();
proto.constructor = URShiftAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " >>>= ", this.right, ")" ].join("");
};



function BitAndAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = BitAndAssignExpression.prototype = new AssignExpression();
proto.constructor = BitAndAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " &= ", this.right, ")" ].join("");
};



function BitXorAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = BitXorAssignExpression.prototype = new AssignExpression();
proto.constructor = BitXorAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " ^= ", this.right, ")" ].join("");
};



function BitOrAssignExpression ( left, right ) {
  AssignExpression.apply(this, arguments);
}

var proto = BitOrAssignExpression.prototype = new AssignExpression();
proto.constructor = BitOrAssignExpression;

proto.toString = function ( ) {
  return [ "(", this.left, " |= ", this.right, ")" ].join("");
};



function CommaExpression ( left, right ) {
  BinaryExpression.apply(this, arguments);
}

var proto = CommaExpression.prototype = new BinaryExpression();
proto.constructor = CommaExpression;

proto.toString = function ( ) {
  return [ "(", this.left, ", ", this.right, ")" ].join("");
};



          return {
              StrictEqualExpression: StrictEqualExpression, BooleanLiteral: BooleanLiteral, OrExpression: OrExpression, NotExpression: NotExpression, ThisExpression: ThisExpression, BitAndAssignExpression: BitAndAssignExpression, DivExpression: DivExpression, BracketAccessor: BracketAccessor, CommaExpression: CommaExpression, BitAndExpression: BitAndExpression, MulExpression: MulExpression, EqualExpression: EqualExpression, CallExpression: CallExpression, FunctionExpression: FunctionExpression, Elision: Elision, PostIncExpression: PostIncExpression, InstanceofExpression: InstanceofExpression, NullLiteral: NullLiteral, BitXorAssignExpression: BitXorAssignExpression, URShiftExpression: URShiftExpression, ConditionalExpression: ConditionalExpression, Identifier: Identifier, UnaryExpression: UnaryExpression, BitOrAssignExpression: BitOrAssignExpression, DivAssignExpression: DivAssignExpression, VoidExpression: VoidExpression, TypeofExpression: TypeofExpression, NewExpression: NewExpression, MulAssignExpression: MulAssignExpression, BinaryExpression: BinaryExpression, TrueLiteral: TrueLiteral, AssignExpression: AssignExpression, SubExpression: SubExpression, PreDecExpression: PreDecExpression, RegExpLiteral: RegExpLiteral, DeleteExpression: DeleteExpression, FalseLiteral: FalseLiteral, BitNotExpression: BitNotExpression, GreaterEqualExpression: GreaterEqualExpression, LessEqualExpression: LessEqualExpression, ModExpression: ModExpression, StringLiteral: StringLiteral, LShiftAssignExpression: LShiftAssignExpression, SubAssignExpression: SubAssignExpression, LShiftExpression: LShiftExpression, ModAssignExpression: ModAssignExpression, URShiftAssignExpression: URShiftAssignExpression, NegExpression: NegExpression, PosExpression: PosExpression, AddAssignExpression: AddAssignExpression, ArrayInitializer: ArrayInitializer, LessThanExpression: LessThanExpression, NumberLiteral: NumberLiteral, StrictNotEqualExpression: StrictNotEqualExpression, RShiftExpression: RShiftExpression, InExpression: InExpression, BitOrExpression: BitOrExpression, AndExpression: AndExpression, PostDecExpression: PostDecExpression, ObjectInitializer: ObjectInitializer, RShiftAssignExpression: RShiftAssignExpression, Expression: Expression, DotAccessor: DotAccessor, Literal: Literal, SimpleAssignExpression: SimpleAssignExpression, BitXorExpression: BitXorExpression, AddExpression: AddExpression, GreaterThanExpression: GreaterThanExpression, NotEqualExpression: NotEqualExpression, PreIncExpression: PreIncExpression
          };
      }();
  }
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.StrictEqualExpression = StrictEqualExpression;
  this.Concurrent.Thread.Compiler.BooleanLiteral = BooleanLiteral;
  this.Concurrent.Thread.Compiler.OrExpression = OrExpression;
  this.Concurrent.Thread.Compiler.NotExpression = NotExpression;
  this.Concurrent.Thread.Compiler.ThisExpression = ThisExpression;
  this.Concurrent.Thread.Compiler.BitAndAssignExpression = BitAndAssignExpression;
  this.Concurrent.Thread.Compiler.DivExpression = DivExpression;
  this.Concurrent.Thread.Compiler.BracketAccessor = BracketAccessor;
  this.Concurrent.Thread.Compiler.CommaExpression = CommaExpression;
  this.Concurrent.Thread.Compiler.BitAndExpression = BitAndExpression;
  this.Concurrent.Thread.Compiler.MulExpression = MulExpression;
  this.Concurrent.Thread.Compiler.EqualExpression = EqualExpression;
  this.Concurrent.Thread.Compiler.CallExpression = CallExpression;
  this.Concurrent.Thread.Compiler.FunctionExpression = FunctionExpression;
  this.Concurrent.Thread.Compiler.Elision = Elision;
  this.Concurrent.Thread.Compiler.PostIncExpression = PostIncExpression;
  this.Concurrent.Thread.Compiler.InstanceofExpression = InstanceofExpression;
  this.Concurrent.Thread.Compiler.NullLiteral = NullLiteral;
  this.Concurrent.Thread.Compiler.BitXorAssignExpression = BitXorAssignExpression;
  this.Concurrent.Thread.Compiler.URShiftExpression = URShiftExpression;
  this.Concurrent.Thread.Compiler.ConditionalExpression = ConditionalExpression;
  this.Concurrent.Thread.Compiler.Identifier = Identifier;
  this.Concurrent.Thread.Compiler.UnaryExpression = UnaryExpression;
  this.Concurrent.Thread.Compiler.BitOrAssignExpression = BitOrAssignExpression;
  this.Concurrent.Thread.Compiler.DivAssignExpression = DivAssignExpression;
  this.Concurrent.Thread.Compiler.VoidExpression = VoidExpression;
  this.Concurrent.Thread.Compiler.TypeofExpression = TypeofExpression;
  this.Concurrent.Thread.Compiler.NewExpression = NewExpression;
  this.Concurrent.Thread.Compiler.MulAssignExpression = MulAssignExpression;
  this.Concurrent.Thread.Compiler.BinaryExpression = BinaryExpression;
  this.Concurrent.Thread.Compiler.TrueLiteral = TrueLiteral;
  this.Concurrent.Thread.Compiler.AssignExpression = AssignExpression;
  this.Concurrent.Thread.Compiler.SubExpression = SubExpression;
  this.Concurrent.Thread.Compiler.PreDecExpression = PreDecExpression;
  this.Concurrent.Thread.Compiler.RegExpLiteral = RegExpLiteral;
  this.Concurrent.Thread.Compiler.DeleteExpression = DeleteExpression;
  this.Concurrent.Thread.Compiler.FalseLiteral = FalseLiteral;
  this.Concurrent.Thread.Compiler.BitNotExpression = BitNotExpression;
  this.Concurrent.Thread.Compiler.GreaterEqualExpression = GreaterEqualExpression;
  this.Concurrent.Thread.Compiler.LessEqualExpression = LessEqualExpression;
  this.Concurrent.Thread.Compiler.ModExpression = ModExpression;
  this.Concurrent.Thread.Compiler.StringLiteral = StringLiteral;
  this.Concurrent.Thread.Compiler.LShiftAssignExpression = LShiftAssignExpression;
  this.Concurrent.Thread.Compiler.SubAssignExpression = SubAssignExpression;
  this.Concurrent.Thread.Compiler.LShiftExpression = LShiftExpression;
  this.Concurrent.Thread.Compiler.ModAssignExpression = ModAssignExpression;
  this.Concurrent.Thread.Compiler.URShiftAssignExpression = URShiftAssignExpression;
  this.Concurrent.Thread.Compiler.NegExpression = NegExpression;
  this.Concurrent.Thread.Compiler.PosExpression = PosExpression;
  this.Concurrent.Thread.Compiler.AddAssignExpression = AddAssignExpression;
  this.Concurrent.Thread.Compiler.ArrayInitializer = ArrayInitializer;
  this.Concurrent.Thread.Compiler.LessThanExpression = LessThanExpression;
  this.Concurrent.Thread.Compiler.NumberLiteral = NumberLiteral;
  this.Concurrent.Thread.Compiler.StrictNotEqualExpression = StrictNotEqualExpression;
  this.Concurrent.Thread.Compiler.RShiftExpression = RShiftExpression;
  this.Concurrent.Thread.Compiler.InExpression = InExpression;
  this.Concurrent.Thread.Compiler.BitOrExpression = BitOrExpression;
  this.Concurrent.Thread.Compiler.AndExpression = AndExpression;
  this.Concurrent.Thread.Compiler.PostDecExpression = PostDecExpression;
  this.Concurrent.Thread.Compiler.ObjectInitializer = ObjectInitializer;
  this.Concurrent.Thread.Compiler.RShiftAssignExpression = RShiftAssignExpression;
  this.Concurrent.Thread.Compiler.Expression = Expression;
  this.Concurrent.Thread.Compiler.DotAccessor = DotAccessor;
  this.Concurrent.Thread.Compiler.Literal = Literal;
  this.Concurrent.Thread.Compiler.SimpleAssignExpression = SimpleAssignExpression;
  this.Concurrent.Thread.Compiler.BitXorExpression = BitXorExpression;
  this.Concurrent.Thread.Compiler.AddExpression = AddExpression;
  this.Concurrent.Thread.Compiler.GreaterThanExpression = GreaterThanExpression;
  this.Concurrent.Thread.Compiler.NotEqualExpression = NotEqualExpression;
  this.Concurrent.Thread.Compiler.PreIncExpression = PreIncExpression;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( this.Concurrent.Thread.Compiler.Token === undefined ) this.Concurrent.Thread.Compiler.Token = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Roger Lawrence
*   Mike McCabe
*   Igor Bukanov
*   Milen Nankov
*   Daisuke Maki
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

/**
* This file is based on the file Token.java in Rhino 1.6R5.
*/





NAMESPACE = 'Concurrent.Thread.Compiler';







var Token = {};

// Although Token is in fact a namespace, we here implements it
// "manually" because of efficiency.


// start enum
Token.ERROR          = -1; // well-known as the only code < EOF
Token.EOF            = 0;  // end of file token - (not EOF_CHAR)
Token.EOL            = 1;  // end of line

// Interpreter reuses the following as bytecodes
Token.FIRST_BYTECODE_TOKEN    = 2;

Token.ENTERWITH      = 2;
Token.LEAVEWITH      = 3;
Token.RETURN         = 4;
Token.GOTO           = 5;
Token.IFEQ           = 6;
Token.IFNE           = 7;
Token.SETNAME        = 8;
Token.BITOR          = 9;
Token.BITXOR         = 10;
Token.BITAND         = 11;
Token.EQ             = 12;
Token.NE             = 13;
Token.LT             = 14;
Token.LE             = 15;
Token.GT             = 16;
Token.GE             = 17;
Token.LSH            = 18;
Token.RSH            = 19;
Token.URSH           = 20;
Token.ADD            = 21;
Token.SUB            = 22;
Token.MUL            = 23;
Token.DIV            = 24;
Token.MOD            = 25;
Token.NOT            = 26;
Token.BITNOT         = 27;
Token.POS            = 28;
Token.NEG            = 29;
Token.NEW            = 30;
Token.DELPROP        = 31;
Token.TYPEOF         = 32;
Token.GETPROP        = 33;
Token.SETPROP        = 34;
Token.GETELEM        = 35;
Token.SETELEM        = 36;
Token.CALL           = 37;
Token.NAME           = 38;
Token.NUMBER         = 39;
Token.STRING         = 40;
Token.NULL           = 41;
Token.THIS           = 42;
Token.FALSE          = 43;
Token.TRUE           = 44;
Token.SHEQ           = 45;   // shallow equality (===)
Token.SHNE           = 46;   // shallow inequality (!==)
Token.REGEXP         = 47;
Token.BINDNAME       = 48;
Token.THROW          = 49;
Token.RETHROW        = 50; // rethrow caught execetion: catch (e if ) use it
Token.IN             = 51;
Token.INSTANCEOF     = 52;
Token.LOCAL_LOAD     = 53;
Token.GETVAR         = 54;
Token.SETVAR         = 55;
Token.CATCH_SCOPE    = 56;
Token.ENUM_INIT_KEYS = 57;
Token.ENUM_INIT_VALUES = 58;
Token.ENUM_NEXT      = 59;
Token.ENUM_ID        = 60;
Token.THISFN         = 61;
Token.RETURN_RESULT  = 62; // to return prevoisly stored return result
Token.ARRAYLIT       = 63; // array literal
Token.OBJECTLIT      = 64; // object literal
Token.GET_REF        = 65; // *reference
Token.SET_REF        = 66; // *reference    : something
Token.DEL_REF        = 67; // delete reference
Token.REF_CALL       = 68; // f(args)    = something or f(args)++
Token.REF_SPECIAL    = 69; // reference for special properties like __proto

// For XML support:
Token.DEFAULTNAMESPACE = 70; // default xml namespace =
Token.ESCXMLATTR     = 71;
Token.ESCXMLTEXT     = 72;
Token.REF_MEMBER     = 73; // Reference for x.@y, x..y etc.
Token.REF_NS_MEMBER  = 74; // Reference for x.ns::y, x..ns::y etc.
Token.REF_NAME       = 75; // Reference for @y, @[y] etc.
Token.REF_NS_NAME    = 76; // Reference for ns::y, @ns::y@[y] etc.

// End of interpreter bytecodes

Token.LAST_BYTECODE_TOKEN = Token.REF_NS_NAME;

Token.TRY            = 77;
Token.SEMI           = 78;  // semicolon
Token.LB             = 79;  // left and right brackets
Token.RB             = 80;
Token.LC             = 81;  // left and right curlies (braces)
Token.RC             = 82;
Token.LP             = 83;  // left and right parentheses
Token.RP             = 84;
Token.COMMA          = 85;  // comma operator

Token.ASSIGN         = 86;  // simple assignment  (=)
Token.ASSIGN_BITOR   = 87;  // |=
Token.ASSIGN_BITXOR  = 88;  // ^=
Token.ASSIGN_BITAND  = 89;  // |=
Token.ASSIGN_LSH     = 90;  // <<=
Token.ASSIGN_RSH     = 91;  // >>=
Token.ASSIGN_URSH    = 92;  // >>>=
Token.ASSIGN_ADD     = 93;  // +=
Token.ASSIGN_SUB     = 94;  // -=
Token.ASSIGN_MUL     = 95;  // *=
Token.ASSIGN_DIV     = 96;  // /=
Token.ASSIGN_MOD     = 97;  // %=

Token.FIRST_ASSIGN   = Token.ASSIGN;
Token.LAST_ASSIGN    = Token.ASSIGN_MOD;

Token.HOOK           = 98; // conditional (?:)
Token.COLON          = 99;
Token.OR             = 100; // logical or (||)
Token.AND            = 101; // logical and (&&)
Token.INC            = 102; // increment/decrement (++ --)
Token.DEC            = 103;
Token.DOT            = 104; // member operator (.)
Token.FUNCTION       = 105; // function keyword
Token.EXPORT         = 106; // export keyword
Token.IMPORT         = 107; // import keyword
Token.IF             = 108; // if keyword
Token.ELSE           = 109; // else keyword
Token.SWITCH         = 110; // switch keyword
Token.CASE           = 111; // case keyword
Token.DEFAULT        = 112; // default keyword
Token.WHILE          = 113; // while keyword
Token.DO             = 114; // do keyword
Token.FOR            = 115; // for keyword
Token.BREAK          = 116; // break keyword
Token.CONTINUE       = 117; // continue keyword
Token.VAR            = 118; // var keyword
Token.WITH           = 119; // with keyword
Token.CATCH          = 120; // catch keyword
Token.FINALLY        = 121; // finally keyword
Token.VOID           = 122; // void keyword
Token.RESERVED       = 123; // reserved keywords

Token.EMPTY          = 124;

/* types used for the parse tree - these never get returned
* by the scanner.
*/

Token.BLOCK          = 125; // statement block
Token.LABEL          = 126; // label
Token.TARGET         = 127;
Token.LOOP           = 128;
Token.EXPR_VOID      = 129; // expression statement in functions
Token.EXPR_RESULT    = 130; // expression statement in scripts
Token.JSR            = 131;
Token.SCRIPT         = 132; // top-level node for entire script
Token.TYPEOFNAME     = 133; // for typeof(simple-name)
Token.USE_STACK      = 134;
Token.SETPROP_OP     = 135; // x.y op= something
Token.SETELEM_OP     = 136; // x[y] op= something
Token.LOCAL_BLOCK    = 137;
Token.SET_REF_OP     = 138; // *reference op= something

// For XML support:
Token.DOTDOT         = 139;  // member operator (..)
Token.COLONCOLON     = 140;  // namespace::name
Token.XML            = 141;  // XML type
Token.DOTQUERY       = 142;  // .() -- e.g., x.emps.emp.(name == "terry")
Token.XMLATTR        = 143;  // @
Token.XMLEND         = 144;

// Optimizer-only-tokens
Token.TO_OBJECT      = 145;
Token.TO_DOUBLE      = 146;

Token.LAST_TOKEN     = 146;


Token.name = function ( token ) 
{
  if ( !Kit.printTrees ) return String(token);
  with ( Token ) {
      switch ( token ) {
        case ERROR:           return "ERROR";
        case EOF:             return "EOF";
        case EOL:             return "EOL";
        case ENTERWITH:       return "ENTERWITH";
        case LEAVEWITH:       return "LEAVEWITH";
        case RETURN:          return "RETURN";
        case GOTO:            return "GOTO";
        case IFEQ:            return "IFEQ";
        case IFNE:            return "IFNE";
        case SETNAME:         return "SETNAME";
        case BITOR:           return "BITOR";
        case BITXOR:          return "BITXOR";
        case BITAND:          return "BITAND";
        case EQ:              return "EQ";
        case NE:              return "NE";
        case LT:              return "LT";
        case LE:              return "LE";
        case GT:              return "GT";
        case GE:              return "GE";
        case LSH:             return "LSH";
        case RSH:             return "RSH";
        case URSH:            return "URSH";
        case ADD:             return "ADD";
        case SUB:             return "SUB";
        case MUL:             return "MUL";
        case DIV:             return "DIV";
        case MOD:             return "MOD";
        case NOT:             return "NOT";
        case BITNOT:          return "BITNOT";
        case POS:             return "POS";
        case NEG:             return "NEG";
        case NEW:             return "NEW";
        case DELPROP:         return "DELPROP";
        case TYPEOF:          return "TYPEOF";
        case GETPROP:         return "GETPROP";
        case SETPROP:         return "SETPROP";
        case GETELEM:         return "GETELEM";
        case SETELEM:         return "SETELEM";
        case CALL:            return "CALL";
        case NAME:            return "NAME";
        case NUMBER:          return "NUMBER";
        case STRING:          return "STRING";
        case NULL:            return "NULL";
        case THIS:            return "THIS";
        case FALSE:           return "FALSE";
        case TRUE:            return "TRUE";
        case SHEQ:            return "SHEQ";
        case SHNE:            return "SHNE";
        case REGEXP:          return "OBJECT";
        case BINDNAME:        return "BINDNAME";
        case THROW:           return "THROW";
        case RETHROW:         return "RETHROW";
        case IN:              return "IN";
        case INSTANCEOF:      return "INSTANCEOF";
        case LOCAL_LOAD:      return "LOCAL_LOAD";
        case GETVAR:          return "GETVAR";
        case SETVAR:          return "SETVAR";
        case CATCH_SCOPE:     return "CATCH_SCOPE";
        case ENUM_INIT_KEYS:  return "ENUM_INIT_KEYS";
        case ENUM_INIT_VALUES:  return "ENUM_INIT_VALUES";
        case ENUM_NEXT:       return "ENUM_NEXT";
        case ENUM_ID:         return "ENUM_ID";
        case THISFN:          return "THISFN";
        case RETURN_RESULT:   return "RETURN_RESULT";
        case ARRAYLIT:        return "ARRAYLIT";
        case OBJECTLIT:       return "OBJECTLIT";
        case GET_REF:         return "GET_REF";
        case SET_REF:         return "SET_REF";
        case DEL_REF:         return "DEL_REF";
        case REF_CALL:        return "REF_CALL";
        case REF_SPECIAL:     return "REF_SPECIAL";
        case DEFAULTNAMESPACE:return "DEFAULTNAMESPACE";
        case ESCXMLTEXT:      return "ESCXMLTEXT";
        case ESCXMLATTR:      return "ESCXMLATTR";
        case REF_MEMBER:      return "REF_MEMBER";
        case REF_NS_MEMBER:   return "REF_NS_MEMBER";
        case REF_NAME:        return "REF_NAME";
        case REF_NS_NAME:     return "REF_NS_NAME";
        case TRY:             return "TRY";
        case SEMI:            return "SEMI";
        case LB:              return "LB";
        case RB:              return "RB";
        case LC:              return "LC";
        case RC:              return "RC";
        case LP:              return "LP";
        case RP:              return "RP";
        case COMMA:           return "COMMA";
        case ASSIGN:          return "ASSIGN";
        case ASSIGN_BITOR:    return "ASSIGN_BITOR";
        case ASSIGN_BITXOR:   return "ASSIGN_BITXOR";
        case ASSIGN_BITAND:   return "ASSIGN_BITAND";
        case ASSIGN_LSH:      return "ASSIGN_LSH";
        case ASSIGN_RSH:      return "ASSIGN_RSH";
        case ASSIGN_URSH:     return "ASSIGN_URSH";
        case ASSIGN_ADD:      return "ASSIGN_ADD";
        case ASSIGN_SUB:      return "ASSIGN_SUB";
        case ASSIGN_MUL:      return "ASSIGN_MUL";
        case ASSIGN_DIV:      return "ASSIGN_DIV";
        case ASSIGN_MOD:      return "ASSIGN_MOD";
        case HOOK:            return "HOOK";
        case COLON:           return "COLON";
        case OR:              return "OR";
        case AND:             return "AND";
        case INC:             return "INC";
        case DEC:             return "DEC";
        case DOT:             return "DOT";
        case FUNCTION:        return "FUNCTION";
        case EXPORT:          return "EXPORT";
        case IMPORT:          return "IMPORT";
        case IF:              return "IF";
        case ELSE:            return "ELSE";
        case SWITCH:          return "SWITCH";
        case CASE:            return "CASE";
        case DEFAULT:         return "DEFAULT";
        case WHILE:           return "WHILE";
        case DO:              return "DO";
        case FOR:             return "FOR";
        case BREAK:           return "BREAK";
        case CONTINUE:        return "CONTINUE";
        case VAR:             return "VAR";
        case WITH:            return "WITH";
        case CATCH:           return "CATCH";
        case FINALLY:         return "FINALLY";
        case RESERVED:        return "RESERVED";
        case EMPTY:           return "EMPTY";
        case BLOCK:           return "BLOCK";
        case LABEL:           return "LABEL";
        case TARGET:          return "TARGET";
        case LOOP:            return "LOOP";
        case EXPR_VOID:       return "EXPR_VOID";
        case EXPR_RESULT:     return "EXPR_RESULT";
        case JSR:             return "JSR";
        case SCRIPT:          return "SCRIPT";
        case TYPEOFNAME:      return "TYPEOFNAME";
        case USE_STACK:       return "USE_STACK";
        case SETPROP_OP:      return "SETPROP_OP";
        case SETELEM_OP:      return "SETELEM_OP";
        case LOCAL_BLOCK:     return "LOCAL_BLOCK";
        case SET_REF_OP:      return "SET_REF_OP";
        case DOTDOT:          return "DOTDOT";
        case COLONCOLON:      return "COLONCOLON";
        case XML:             return "XML";
        case DOTQUERY:        return "DOTQUERY";
        case XMLATTR:         return "XMLATTR";
        case XMLEND:          return "XMLEND";
        case TO_OBJECT:       return "TO_OBJECT";
        case TO_DOUBLE:       return "TO_DOUBLE";
      }
  }
  // Token without name
  Kit.codeBug(token);
};

          return {
              Token: Token
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.Token = Token;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.Statement === undefined ) this.Concurrent.Thread.Compiler.Statement = undefined;
  if ( this.Concurrent.Thread.Compiler.EmptyStatement === undefined ) this.Concurrent.Thread.Compiler.EmptyStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.Block === undefined ) this.Concurrent.Thread.Compiler.Block = undefined;
  if ( this.Concurrent.Thread.Compiler.ExpStatement === undefined ) this.Concurrent.Thread.Compiler.ExpStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.VarStatement === undefined ) this.Concurrent.Thread.Compiler.VarStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.IfStatement === undefined ) this.Concurrent.Thread.Compiler.IfStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.IfElseStatement === undefined ) this.Concurrent.Thread.Compiler.IfElseStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.DoWhileStatement === undefined ) this.Concurrent.Thread.Compiler.DoWhileStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.WhileStatement === undefined ) this.Concurrent.Thread.Compiler.WhileStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForStatement === undefined ) this.Concurrent.Thread.Compiler.ForStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForVarStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForInStatement === undefined ) this.Concurrent.Thread.Compiler.ForInStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForInVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForInVarStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForEachStatement === undefined ) this.Concurrent.Thread.Compiler.ForEachStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ForEachVarStatement === undefined ) this.Concurrent.Thread.Compiler.ForEachVarStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ContinueStatement === undefined ) this.Concurrent.Thread.Compiler.ContinueStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.BreakStatement === undefined ) this.Concurrent.Thread.Compiler.BreakStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.ReturnStatement === undefined ) this.Concurrent.Thread.Compiler.ReturnStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.WithStatement === undefined ) this.Concurrent.Thread.Compiler.WithStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.SwitchStatement === undefined ) this.Concurrent.Thread.Compiler.SwitchStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.CaseClause === undefined ) this.Concurrent.Thread.Compiler.CaseClause = undefined;
  if ( this.Concurrent.Thread.Compiler.DefaultClause === undefined ) this.Concurrent.Thread.Compiler.DefaultClause = undefined;
  if ( this.Concurrent.Thread.Compiler.ThrowStatement === undefined ) this.Concurrent.Thread.Compiler.ThrowStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.TryCatchStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.TryFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryFinallyStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.TryCatchFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchFinallyStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.TryCatchListStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchListStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement === undefined ) this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.CatchGuard === undefined ) this.Concurrent.Thread.Compiler.CatchGuard = undefined;
  if ( this.Concurrent.Thread.Compiler.FunctionDeclaration === undefined ) this.Concurrent.Thread.Compiler.FunctionDeclaration = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';










function Statement ( labels, lineno, source ) {
  // This is kind of abstract class.
  this.labels = labels;  // array of Identifier  # labels directly qualifying this statement
  this.lineno = lineno;  // Number (optional)    # line no. 
  this.source = source;  // String (optional)    # file-name, URL, ...etc
}

Statement.prototype.toString = function ( ) {
  Kit.codeBug();
};

// kind of final protected method.
// Use this like: labelsToString.call(obj, arg0, arg1 ...)
function labelsToString ( ) {
  var buf = [];
  for ( var i=0;  i < this.labels.length;  i++ ) {
      buf.push(this.labels[i], ": ");
  }
  return buf.join("");
}



function EmptyStatement ( labels, lineno, source ) {
  Statement.call(this, labels, lineno, source);
}

var proto = EmptyStatement.prototype = new Statement();
proto.constructor = EmptyStatement;

proto.toString = function ( ) {
  return labelsToString.call(this) + ";";
};



function Block ( labels, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.body = body;  // cons-list of Statement
}

var proto = Block.prototype = new Statement();
proto.constructor = Block;

proto.toString = function ( ) {
  var buf = [labelsToString.call(this), "{"];
  this.body.forEach(function( it ){
      buf.push(it);
  });
  buf.push("}");
  return buf.join("\n");
};



function ExpStatement ( labels, exp, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.exp = exp;  // Expression
}

var proto = ExpStatement.prototype = new Statement();
proto.constructor = ExpStatement;

proto.toString = function ( ) {
  return labelsToString.call(this) + String(this.exp) + ";";
};

proto.containsFunctionCall = function ( ) {
  return this.exp.containsFunctionCall();
};



function VarStatement ( labels, decls, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.decls = decls;  // array of {id: Identifier,  exp: Expression or null}
}

var proto = VarStatement.prototype = new Statement();
proto.constructor = VarStatement;

proto.toString = function ( ) {
  var buf = [];
  for ( var i=0;  i < this.decls.length;  i++ ) {
      if ( this.decls[i].exp ) {
          buf.push( [ this.decls[i].id, "=", this.decls[i].exp ].join("") );
      }
      else {
          buf.push( this.decls[i].id );
      }
  }
  return [ labelsToString.call(this),
           "var ",
           buf.join(", "),
           ";",
         ].join("");
};

proto.containsFunctionCall = function ( ) {
  for ( var i=0;  i < this.decls.length;  i++ ) {
      if ( this.decls[i].exp && this.decls[i].exp.containsFunctionCall() ) {
          return true;
      }
  }
  return false;
};



function IfStatement ( labels, cond, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.cond = cond;  // Expression
  this.body = body;  // Statement
}

var proto = IfStatement.prototype = new Statement();
proto.constructor = IfStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "if (",
           this.cond,
           ") ",
           this.body
         ].join("");
};



function IfElseStatement ( labels, cond, tbody, fbody, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.cond  = cond;   // Expression
  this.tbody = tbody;  // Statement
  this.fbody = fbody;  // Statement
}

var proto = IfElseStatement.prototype = new Statement();
proto.constructor = IfElseStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "if (",
           this.cond,
           ") ",
           this.tbody,
           "\n",
           "else ",
           this.fbody
         ].join("");
};



function DoWhileStatement ( labels, body, cond, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.body = body;  // Statement
  this.cond = cond;  // Expression
}

var proto = DoWhileStatement.prototype = new Statement();
proto.constructor = DoWhileStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "do ",
           this.body,
           " while (",
           this.cond,
           ");"
         ].join("");
};



function WhileStatement ( labels, cond, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.cond = cond;  // Expression
  this.body = body;  // Statement
}

var proto = WhileStatement.prototype = new Statement();
proto.constructor = WhileStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "while (",
           this.cond,
           ") ",
           this.body
         ].join("");
};



function ForStatement ( labels, init, cond, incr, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.init = init;  // Expression or null
  this.cond = cond;  // Expression or null
  this.incr = incr;  // Expression or null
  this.body = body;  // Statement
}

var proto = ForStatement.prototype = new Statement();
proto.constructor = ForStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for (",
           this.init ? this.init : "", "; ",
           this.cond ? this.cond : "", "; ",
           this.incr ? this.incr : "",
           ") ",
           this.body
         ].join("");
};



function ForVarStatement ( labels, decls, cond, incr, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.decls = decls;  // array of {id: Identifier,  exp: Expression or null}
  this.cond  = cond;   // Expression or null
  this.incr  = incr;   // Expression or null
  this.body  = body;   // Statement
}

var proto = ForVarStatement.prototype = new Statement();
proto.constructor = ForVarStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for (",
           (this.decls.length ? new VarStatement([], this.decls) : ";"), " ",
           this.cond ? this.cond : "", "; ",
           this.incr ? this.incr : "",
           ") ",
           this.body
         ].join("");
};



function ForInStatement ( labels, lhs, exp, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.lhs  = lhs;   // Identifier or DotAccessor or BracketAccessor
  this.exp  = exp;   // Expression
  this.body = body;  // Statement
}

var proto = ForInStatement.prototype = new Statement();
proto.constructor = ForInStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for (", this.lhs, " in ", this.exp, ") ",
           this.body
         ].join("");
};



function ForInVarStatement ( labels, decl, exp, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.decl = decl;  // {id: Identifier,  exp: Expression or null}
  this.exp  = exp;   // Expression
  this.body = body;  // Statement
}

var proto = ForInVarStatement.prototype = new Statement();
proto.constructor = ForInVarStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for ( var ",
           this.decl.exp ? String(this.decl.id) + "=" + String(this.decl.exp)
                         : String(this.decl.id),
           " in ",
           this.exp,
           ") ",
           this.body
         ].join("");
};


// Mozilla extention "for each ( ... in ... )"

function ForEachStatement ( labels, lhs, exp, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.lhs  = lhs;   // Identifier or DotAccessor or BracketAccessor
  this.exp  = exp;   // Expression
  this.body = body;  // Statement
}

var proto = ForEachStatement.prototype = new Statement();
proto.constructor = ForEachStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for each (", this.lhs, " in ", this.exp, ") ",
           this.body
         ].join("");
};



function ForEachVarStatement ( labels, decl, exp, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.decl = decl;  // {id: Identifier,  exp: Expression or null}
  this.exp  = exp;   // Expression
  this.body = body;  // Statement
}

var proto = ForEachVarStatement.prototype = new Statement();
proto.constructor = ForEachVarStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "for each ( var ",
           this.decl.exp ? String(this.decl.id) + "=" + String(this.decl.exp)
                         : String(this.decl.id),
           " in ",
           this.exp,
           ") ",
           this.body
         ].join("");
};



function ContinueStatement ( labels, target, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.target = target;  // Identifier or null
}

var proto = ContinueStatement.prototype = new Statement();
proto.constructor = ContinueStatement;

proto.toString = function ( ) {
  var buf = [labelsToString.call(this), "continue"];
  if ( this.target ) buf.push(" ", this.target);
  buf.push(";");
  return buf.join("");
};



function BreakStatement ( labels, target, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.target = target;  // Identifier or null
}

var proto = BreakStatement.prototype = new Statement();
proto.constructor = BreakStatement;

proto.toString = function ( ) {
  var buf = [labelsToString.call(this), "break"];
  if ( this.target ) buf.push(" ", this.target);
  buf.push(";");
  return buf.join("");
};



function ReturnStatement ( labels, exp, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.exp = exp;  // Expression or null
}

var proto = ReturnStatement.prototype = new Statement();
proto.constructor = ReturnStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "return ",
           this.exp ? this.exp : "",
           ";"
         ].join("");
};



function WithStatement ( labels, exp, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.exp  = exp;   // Expression
  this.body = body;  // Statement
}

var proto = WithStatement.prototype = new Statement();
proto.constructor = WithStatement;

proto.toString = function ( ) {
  return [ "with (", this.exp, ") ", this.body ].join("");
};



function SwitchStatement ( labels, exp, clauses, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.exp     = exp;      // Expression
  this.clauses = clauses;  // cons-list of (CaseClause or DefaultClause)
}

var proto = SwitchStatement.prototype = new Statement();
proto.constructor = SwitchStatement;

proto.toString = function ( ) {
  var buf = [ "switch ( ", this.exp, ") {\n"];
  this.clauses.forEach(function( it ){
      buf.push(it, "\n");
  });
  buf.push("}");
  return buf.join("");
};



function CaseClause ( exp, body, lineno, source ) {
  this.exp    = exp;     // Expression
  this.body   = body;    // cons-list of Statement
  this.lineno = lineno;  // Number (optional)
  this.source = source;  // String (optional)
}

CaseClause.prototype.toString = function ( ) {
  var buf = ["case ", this.exp, ":\n"];
  this.body.forEach(function( it ){
      buf.push(it, "\n");
  });
  return buf.join("");
};



function DefaultClause ( body, lineno, source ) {
  this.body   = body;    // cons-list of Statement
  this.lineno = lineno;  // Number (optional)
  this.source = source;  // String (optional)
}

DefaultClause.prototype.toString = function ( ) {
  var buf = ["default:\n"];
  this.body.forEach(function( it ){
      buf.push(it, "\n");
  });
  return buf.join("");
};



function ThrowStatement ( labels, exp, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.exp = exp;  // Expression
}

var proto = ThrowStatement.prototype = new Statement();
proto.constructor = ThrowStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "throw ", this.exp, ";"
         ].join("");
};



function TryCatchStatement ( labels, tryBlock, variable, catchBlock, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.tryBlock   = tryBlock;    // Block
  this.variable   = variable;    // Identifier
  this.catchBlock = catchBlock;  // Block
}

var proto = TryCatchStatement.prototype = new Statement();
proto.constructor = TryCatchStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "try ", this.tryBlock, "\n",
           "catch (", this.variable, ") ", this.catchBlock
         ].join("");
};



function TryFinallyStatement ( labels, tryBlock, finallyBlock, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.tryBlock     = tryBlock;      // Block
  this.finallyBlock = finallyBlock;  // Block
}

var proto = TryFinallyStatement.prototype = new Statement();
proto.constructor = TryFinallyStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "try ", this.tryBlock, "\n",
           "finally ", this.finallyBlock
         ].join("");
};



function TryCatchFinallyStatement ( labels, tryBlock, variable, catchBlock, finallyBlock, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.tryBlock     = tryBlock;      // Block
  this.variable     = variable;      // Identifier
  this.catchBlock   = catchBlock;    // Block
  this.finallyBlock = finallyBlock;  // Block
}

var proto = TryCatchFinallyStatement.prototype = new Statement();
proto.constructor = TryCatchFinallyStatement;

proto.toString = function ( ) {
  return [ labelsToString.call(this),
           "try ", this.tryBlock, "\n",
           "catch (", this.variable, ") ", this.catchBlock, "\n",
           "finally ", this.finallyBlock
         ].join("");
};



function TryCatchListStatement ( labels, tryBlock, catchList, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.tryBlock  = tryBlock;   // Block
  this.catchList = catchList;  // cons-list of CatchGuard
}

var proto = TryCatchListStatement.prototype = new Statement();
proto.constructor = TryCatchListStatement;

proto.toString = function ( ) {
  var buf = [ labelsToString.call(this),
              "try ", this.tryBlock, "\n" ];
  this.catchList.forEach(function( it ){
      buf.push(it);
  });
  return buf.join("");
};



function TryCatchListFinallyStatement ( labels, tryBlock, catchList, finallyBlock, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.tryBlock     = tryBlock;      // Block
  this.catchList    = catchList;     // cons-list of CatchGuard
  this.finallyBlock = finallyBlock;  // Block
}

var proto = TryCatchListFinallyStatement.prototype = new Statement();
proto.constructor = TryCatchListFinallyStatement;

proto.toString = function ( ) {
  var buf = [ labelsToString.call(this),
              "try ", this.tryBlock, "\n" ];
  this.catchList.forEach(function( it ){
      buf.push(it);
  });
  buf.push("finally ", this.finallyBlock);
  return buf.join("");
};



function CatchGuard ( variable, cond, block, lineno, source ) {
  this.variable = variable;  // Identifier
  this.cond     = cond;      // Expression or null (null means this is default catch clause)
  this.block    = block;     // Block
  this.lineno   = lineno;    // Number (optional)
  this.source   = source;    // String (optional)
}

CatchGuard.prototype.toString = function ( ) {
  var buf = ["catch ( ", this.variable];
  if ( this.cond ) buf.push(" if ", this.cond);
  buf.push(" )", this.block);
  return buf.join("");
};



function FunctionDeclaration ( labels, name, params, body, lineno, source ) {
  Statement.call(this, labels, lineno, source);
  this.name   = name;    // Identifier
  this.params = params;  // array of Identifier
  this.body   = body;    // cons-list of Statement
}

var proto = FunctionDeclaration.prototype = new Statement();
proto.constructor = FunctionDeclaration;

proto.toString = function ( ) {
  var buf = [ "function ", this.name,
              " (", this.params.join(", "), ") {\n" ];
  this.body.forEach(function( it ){
      buf.push(it, "\n");
  });
  buf.push("}");
  return buf.join("");
};


          return {
              CatchGuard: CatchGuard, Block: Block, IfStatement: IfStatement, FunctionDeclaration: FunctionDeclaration, ForVarStatement: ForVarStatement, IfElseStatement: IfElseStatement, TryFinallyStatement: TryFinallyStatement, TryCatchFinallyStatement: TryCatchFinallyStatement, ThrowStatement: ThrowStatement, ForEachStatement: ForEachStatement, EmptyStatement: EmptyStatement, TryCatchStatement: TryCatchStatement, WithStatement: WithStatement, ExpStatement: ExpStatement, ReturnStatement: ReturnStatement, Statement: Statement, ForInVarStatement: ForInVarStatement, BreakStatement: BreakStatement, TryCatchListStatement: TryCatchListStatement, DoWhileStatement: DoWhileStatement, ForInStatement: ForInStatement, DefaultClause: DefaultClause, VarStatement: VarStatement, ContinueStatement: ContinueStatement, TryCatchListFinallyStatement: TryCatchListFinallyStatement, WhileStatement: WhileStatement, SwitchStatement: SwitchStatement, ForEachVarStatement: ForEachVarStatement, CaseClause: CaseClause, ForStatement: ForStatement
          };
      }();
  }
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CatchGuard = CatchGuard;
  this.Concurrent.Thread.Compiler.Block = Block;
  this.Concurrent.Thread.Compiler.IfStatement = IfStatement;
  this.Concurrent.Thread.Compiler.FunctionDeclaration = FunctionDeclaration;
  this.Concurrent.Thread.Compiler.ForVarStatement = ForVarStatement;
  this.Concurrent.Thread.Compiler.IfElseStatement = IfElseStatement;
  this.Concurrent.Thread.Compiler.TryFinallyStatement = TryFinallyStatement;
  this.Concurrent.Thread.Compiler.TryCatchFinallyStatement = TryCatchFinallyStatement;
  this.Concurrent.Thread.Compiler.ThrowStatement = ThrowStatement;
  this.Concurrent.Thread.Compiler.ForEachStatement = ForEachStatement;
  this.Concurrent.Thread.Compiler.EmptyStatement = EmptyStatement;
  this.Concurrent.Thread.Compiler.TryCatchStatement = TryCatchStatement;
  this.Concurrent.Thread.Compiler.WithStatement = WithStatement;
  this.Concurrent.Thread.Compiler.ExpStatement = ExpStatement;
  this.Concurrent.Thread.Compiler.ReturnStatement = ReturnStatement;
  this.Concurrent.Thread.Compiler.Statement = Statement;
  this.Concurrent.Thread.Compiler.ForInVarStatement = ForInVarStatement;
  this.Concurrent.Thread.Compiler.BreakStatement = BreakStatement;
  this.Concurrent.Thread.Compiler.TryCatchListStatement = TryCatchListStatement;
  this.Concurrent.Thread.Compiler.DoWhileStatement = DoWhileStatement;
  this.Concurrent.Thread.Compiler.ForInStatement = ForInStatement;
  this.Concurrent.Thread.Compiler.DefaultClause = DefaultClause;
  this.Concurrent.Thread.Compiler.VarStatement = VarStatement;
  this.Concurrent.Thread.Compiler.ContinueStatement = ContinueStatement;
  this.Concurrent.Thread.Compiler.TryCatchListFinallyStatement = TryCatchListFinallyStatement;
  this.Concurrent.Thread.Compiler.WhileStatement = WhileStatement;
  this.Concurrent.Thread.Compiler.SwitchStatement = SwitchStatement;
  this.Concurrent.Thread.Compiler.ForEachVarStatement = ForEachVarStatement;
  this.Concurrent.Thread.Compiler.CaseClause = CaseClause;
  this.Concurrent.Thread.Compiler.ForStatement = ForStatement;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( this.Concurrent.Thread.Compiler.IdentifierMap === undefined ) this.Concurrent.Thread.Compiler.IdentifierMap = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';





var hasOwnProperty = Object.prototype.hasOwnProperty;




function IdentifierMap ( ) {
  this._map = {};
}

var proto = IdentifierMap.prototype;


proto.clone = function clone ( ) {
  var c = new IdentifierMap();
  for ( var i in this._map ) {
      if ( hasOwnProperty.call(this._map, i) ) c._map[i] = this._map[i];
  }
  return c;
};


proto.exists = function ( /* variable arguments */ ) {
  for ( var i=0;  i < arguments.length;  i++ ) {
      var key = arguments[i];
      if ( !(key instanceof Identifier) ) throw new TypeError("arguments[" + i + "] is not of type Identifier");
      if ( !hasOwnProperty.call(this._map, key.valueOf()) ) return false;
  }
  return true;
};


proto.get = function ( k ) {
  if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
  var s = k.valueOf();
  if ( !hasOwnProperty.call(this._map, s) ) return undefined;
  return this._map[s].value;
};


proto.put = function ( k, v ) {
  if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
  this._map[k.valueOf()] = {id: k, value: v};
};


proto.remove = function ( k ) {
  if ( !(k instanceof Identifier) ) throw new TypeError("arguments[0] is not of type Identifier");
  return delete this._map[k.valueOf()];
};


proto.keys = function ( ) {
  var set = new IdentifierSet();
  for ( var i in this._map ) {
      if ( hasOwnProperty.call(this._map, i) ) set.add(this._map[i].id);
  }
  return set;
};


proto.values = function ( ) {
  var vals = [];
  for ( var i in this._map ) {
      if ( hasOwnProperty.call(this._map, i) ) vals.push(this._map[i].value);
  }
  return vals;
};


          return {
              IdentifierMap: IdentifierMap
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.IdentifierMap = IdentifierMap;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( this.Concurrent.Thread.Compiler.TokenStream === undefined ) this.Concurrent.Thread.Compiler.TokenStream = undefined;
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Roger Lawrence
*   Mike McCabe
*   Igor Bukanov
*   Ethan Hugg
*   Terry Lucas
*   Milen Nankov
*   Daisuke Maki
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

/**
* This file is based on the file TokenStream.java in Rhino 1.6R5.
*/





NAMESPACE = 'Concurrent.Thread.Compiler';







/*
* For chars - because we need something out-of-range
* to check.  (And checking EOF by exception is annoying.)
* Fortunatelly, U+FFFF is guaranteed not to be assigned 
* for any character.
* Note distinction from EOF token type!
*/
var EOF_CHAR = String.fromCharCode(0xFFFF);




function TokenStream( parser, sourceString, lineno )
{
  this.parser = parser;
  this.sourceString = String(sourceString);
  this.sourceEnd    = this.sourceString.length;
  this.sourceCursor = 0;

  // stuff other than whitespace since start of line
  this.dirtyLine = false;

  this.string = "";

  this.stringBuffer = [];
  this.ungetBuffer  = [];

  this.hitEOF = false;

  this.lineStart   = 0;
  this.lineno      = Number(lineno) || 1;
  this.lineEndChar = undefined;

  // for xml tokenizer
  this.xmlIsAttribute   = false;
  this.xmlIsTagContent  = false;
  this.xmlOpenTagsCount = 0;
}

var proto = TokenStream.prototype;


/* This function uses the cached op, string and number fields in
* TokenStream; if getToken has been called since the passed token
* was scanned, the op or string printed may be incorrect.
*/
proto.tokenToString = function ( token )
{
  if (Token.printTrees) {
      var name = Token.name(token);

      switch ( token ) {
      case Token.STRING:
      case Token.REGEXP:
      case Token.NAME:
          return name + " `" + this.string + "'";

      case Token.NUMBER:
          return "NUMBER " + this.number;
      }

      return name;
  }
  return "";
};


function isKeyword ( s )
{
  return Token.EOF != stringToKeyword(s);
}


var strIdMap = {
  "break"         : Token.BREAK,
  "case"          : Token.CASE,
  "catch"         : Token.CATCH,
  "continue"      : Token.CONTINUE,
  "default"       : Token.DEFAULT,
  "delete"        : Token.DELPROP,
  "do"            : Token.DO,
  "else"          : Token.ELSE,
  "export"        : Token.EXPORT,
  "false"         : Token.FALSE,
  "finally"       : Token.FINALLY,
  "for"           : Token.FOR,
  "function"      : Token.FUNCTION,
  "if"            : Token.IF,
  "in"            : Token.IN,
  "instanceof"    : Token.INSTANCEOF,
  "new"           : Token.NEW,
  "null"          : Token.NULL,
  "return"        : Token.RETURN,
  "switch"        : Token.SWITCH,
  "this"          : Token.THIS,
  "throw"         : Token.THROW,
  "true"          : Token.TRUE,
  "try"           : Token.TRY,
  "typeof"        : Token.TYPEOF,
  "var"           : Token.VAR,
  "void"          : Token.VOID,
  "while"         : Token.WHILE,
  "with"          : Token.WITH,
  // Future Reserved Words
  "abstract"      : Token.RESERVED,
  "boolean"       : Token.RESERVED,
  "byte"          : Token.RESERVED,
  "char"          : Token.RESERVED,
  "class"         : Token.RESERVED,
  "const"         : Token.RESERVED,
  "debugger"      : Token.RESERVED,
  "double"        : Token.RESERVED,
  "enum"          : Token.RESERVED,
  "extends"       : Token.RESERVED,
  "final"         : Token.RESERVED,
  "float"         : Token.RESERVED,
  "goto"          : Token.RESERVED,
  "implements"    : Token.RESERVED,
  "import"        : Token.IMPORT,
  "int"           : Token.RESERVED,
  "interface"     : Token.RESERVED,
  "long"          : Token.RESERVED,
  "native"        : Token.RESERVED,
  "package"       : Token.RESERVED,
  "private"       : Token.RESERVED,
  "protected"     : Token.RESERVED,
  "public"        : Token.RESERVED,
  "short"         : Token.RESERVED,
  "static"        : Token.RESERVED,
  "super"         : Token.RESERVED,
  "synchronized"  : Token.RESERVED,
  "throws"        : Token.RESERVED,
  "transient"     : Token.RESERVED,
  "volatile"      : Token.RESERVED
};

function stringToKeyword ( name )
{
  return strIdMap.hasOwnProperty(name) ? strIdMap[name] : Token.EOF;
}


proto.getLineno = function ( ) { return this.lineno; };

proto.getString = function ( ) { return this.string; };

proto.eof = function ( ) { return this.hitEOF; };


proto.getToken = function ( )
{
  var c;

retry:
  for (;;) {
      // Eat whitespace, possibly sensitive to newlines.
      for (;;) {
          c = this.getChar();
          if ( c === EOF_CHAR ) {
              return Token.EOF;
          } else if ( c === '\n' ) {
              this.dirtyLine = false;
              return Token.EOL;
          } else if ( !isSpace(c) ) {
              if ( c !== '-' ) {
                  this.dirtyLine = true;
              }
              break;
          }
      }

      // identifier/keyword/instanceof?
      // watch out for starting with a <backslash>
      var identifierStart      = false;
      var isUnicodeEscapeStart = false;
      if ( c === '\\' ) {
          c = this.getChar();
          if ( c === 'u' ) {
              identifierStart      = true;
              isUnicodeEscapeStart = true;
              this.stringBuffer    = ["\\u"];
          } else {
              identifierStart = false;
              this.ungetChar(c);
              c = '\\';
          }
      } else if ( isIdentifierStart(c) ) {
          identifierStart   = true;
          this.stringBuffer = [c];
      }

      if ( identifierStart ) {
          var containsEscape = isUnicodeEscapeStart;
          for (;;) {
              if ( isUnicodeEscapeStart ) {
                  // strictly speaking we should probably push-back
                  // all the bad characters if the <backslash>uXXXX
                  // sequence is malformed. But since there isn't a
                  // correct context(is there?) for a bad Unicode
                  // escape sequence in an identifier, we can report
                  // an error here.
                  for ( var i=0;  i != 4;  ++i ) {
                      c = this.getChar();
                      if ( isHexDigit(c) ) {
                          this.addToString(c);
                      } else {
                          this.parser.addError("msg.invalid.escape");
                          return Token.ERROR;
                      }
                  }
                  isUnicodeEscapeStart = false;
              } else {
                  c = this.getChar();
                  if (c == '\\') {
                      c = this.getChar();
                      if (c == 'u') {
                          this.addToString("\\u");
                          isUnicodeEscapeStart = true;
                          containsEscape       = true;
                      } else {
                          this.parser.addError("msg.illegal.character");
                          return Token.ERROR;
                      }
                  } else {
                      if ( !isIdentifierPart(c) ) break;
                      this.addToString(c);
                  }
              }
          }
          this.ungetChar(c);

          var str = this.getStringFromBuffer();
          if ( !containsEscape ) {
              // OPT we shouldn't have to make a string to
              // check if it's a keyword.

              // Return the corresponding token if it's a keyword
              var result = stringToKeyword(str);
              if ( result != Token.EOF ) return result;
          }
          this.string = str;
          return Token.NAME;
      }

      // is it a number?
      if ( isDigit(c)  ||  (c==='.' && isDigit(this.peekChar())) ) {
          this.stringBuffer = [];
          var base = 10;

          if ( c === '0' ) {
              this.addToString('0');
              c = this.getChar();
              if ( c === 'x' || c === 'X' ) {
                  this.addToString(c);
                  base = 16;
                  c = this.getChar();
              } else if ( isDigit(c) ) {
                  base = 8;
              }
          }

          if ( base === 16 ) {
              while ( isHexDigit(c) ) {
                  this.addToString(c);
                  c = this.getChar();
              }
          } else {
              while ( isDigit(c) ) {
                  /*
                   * We permit 08 and 09 as decimal numbers, which
                   * makes our behavior a superset of the ECMA
                   * numeric grammar.  We might not always be so
                   * permissive, so we warn about it.
                   */
                  if ( base === 8  &&  (c==='8' || c==='9') ) {
                      this.parser.addWarning("msg.bad.octal.literal", c == '8' ? "8" : "9");
                      base = 10;
                  }
                  this.addToString(c);
                  c = this.getChar();
              }
          }

          if ( base === 10 ) {
              if ( c === '.' ) {
                  do {
                      this.addToString(c);
                      c = this.getChar();
                  } while ( isDigit(c) );
              }
              if ( c === 'e' || c === 'E' ) {
                  this.addToString(c);
                  c = this.getChar();
                  if ( c === '+' || c === '-' ) {
                      this.addToString(c);
                      c = this.getChar();
                  }
                  if ( !isDigit(c) ) {
                      this.parser.addError("msg.missing.exponent");
                      return Token.ERROR;
                  }
                  do {
                      this.addToString(c);
                      c = this.getChar();
                  } while ( isDigit(c) );
              }
          }
          this.ungetChar(c);

          this.string = this.getStringFromBuffer();
          return Token.NUMBER;
      }

      // is it a string?
      if ( c === '"' || c === "'" ) {
          var quoteChar = c;
          this.stringBuffer = [c];
          c = this.getChar();
          while ( c !== quoteChar ) {
              if ( c === '\n' || c === EOF_CHAR ) {
                  this.ungetChar(c);
                  this.parser.addError("msg.unterminated.string.lit");
                  return Token.ERROR;
              }
              if ( c === '\\' ) {
                  this.addToString('\\');
                  c = this.getChar();
                  if ( c === '\n' ) {
                      // Remove line terminator after escape to follow
                      // SpiderMonkey and C/C++
                      // But, issue warning since ECMA262-3 does not allow that.
                      this.parser.addWarning("msg.unsafe.string.lit");
                  } else {
                      this.addToString(c);
                  }
              } else {
                  this.addToString(c);
              }
              c = this.getChar();
          }
          this.addToString(quoteChar);
          this.string = this.getStringFromBuffer();
          return Token.STRING;
      }

      switch ( c.charCodeAt(0) ) {
      case 0x3B:  // ';'
          return Token.SEMI;

      case 0x5B:  // '['
          return Token.LB;

      case 0x5D:  // ']'
          return Token.RB;

      case 0x7B:  // '{'
          return Token.LC;

      case 0x7D:  // '}'
          return Token.RC;

      case 0x28:  // '('
          return Token.LP;

      case 0x29:  // ')'
          return Token.RP;

      case 0x2C:  // ','
          return Token.COMMA;

      case 0x3F:  // '?'
          return Token.HOOK;

      case 0x40:  // '@'
          return Token.XMLATTR;

      case 0x3A:  // ':'
          if ( this.matchChar(':') ) {
              return Token.COLONCOLON;
          } else {
              return Token.COLON;
          }

      case 0x2E:  // '.'
          if ( this.matchChar('.') ) {
              return Token.DOTDOT;
          } else if ( this.matchChar('(') ) {
              return Token.DOTQUERY;
          } else {
              return Token.DOT;
          }

      case 0x7C:  // '|'
          if ( this.matchChar('|') ) {
              return Token.OR;
          } else if ( this.matchChar('=') ) {
              return Token.ASSIGN_BITOR;
          } else {
              return Token.BITOR;
          }

      case 0x5E:  // '^'
          if ( this.matchChar('=') ) {
              return Token.ASSIGN_BITXOR;
          } else {
              return Token.BITXOR;
          }

      case 0x26:  // '&'
          if ( this.matchChar('&') ) {
              return Token.AND;
          } else if ( this.matchChar('=') ) {
              return Token.ASSIGN_BITAND;
          } else {
              return Token.BITAND;
          }

      case 0x3D:  // '='
          if ( this.matchChar('=') ) {
              if ( this.matchChar('=') ) {
                  return Token.SHEQ;
              } else {
                  return Token.EQ;
              }
          } else {
              return Token.ASSIGN;
          }

      case 0x21:  // '!'
          if ( this.matchChar('=') ) {
              if ( this.matchChar('=') ) {
                  return Token.SHNE;
              } else {
                  return Token.NE;
              }
          } else {
              return Token.NOT;
          }

      case 0x3C:  // '<'
          /* NB:treat HTML begin-comment as comment-till-eol */
          if ( this.matchChar('!') ) {
              if ( this.matchChar('-') ) {
                  if ( this.matchChar('-') ) {
                      this.skipLine();
                      continue retry;
                  }
                  this.ungetChar('-');
              }
              this.ungetChar('!');
          }
          if ( this.matchChar('<') ) {
              if ( this.matchChar('=') ) {
                  return Token.ASSIGN_LSH;
              } else {
                  return Token.LSH;
              }
          } else {
              if ( this.matchChar('=') ) {
                  return Token.LE;
              } else {
                  return Token.LT;
              }
          }

      case 0x3E:  // '>'
          if ( this.matchChar('>') ) {
              if ( this.matchChar('>') ) {
                  if ( this.matchChar('=') ) {
                      return Token.ASSIGN_URSH;
                  } else {
                      return Token.URSH;
                  }
              } else {
                  if ( this.matchChar('=') ) {
                      return Token.ASSIGN_RSH;
                  } else {
                      return Token.RSH;
                  }
              }
          } else {
              if ( this.matchChar('=') ) {
                  return Token.GE;
              } else {
                  return Token.GT;
              }
          }

      case 0x2A:  // '*'
          if ( this.matchChar('=') ) {
              return Token.ASSIGN_MUL;
          } else {
              return Token.MUL;
          }

      case 0x2F:  // '/'
          // is it a // comment?
          if ( this.matchChar('/') ) {
              this.skipLine();
              continue retry;
          } else if ( this.matchChar('*') ) {
              for (;;) {
                  c = this.getChar();
                  if ( c === EOF_CHAR ) {
                      this.parser.addError("msg.unterminated.comment");
                      return Token.ERROR;
                  } else if ( c === '*' ) {
                      c = this.getChar();
                      if ( c === '/' ) {
                          continue retry;
                      }
                  }
              }
          } else if ( this.matchChar('=') ) {
              return Token.ASSIGN_DIV;
          } else {
              return Token.DIV;
          }

      case 0x25:  // '%'
          if ( this.matchChar('=') ) {
              return Token.ASSIGN_MOD;
          } else {
              return Token.MOD;
          }

      case 0x7E:  // '~'
          return Token.BITNOT;

      case 0x2B:  // '+'
          if ( this.matchChar('=') ) {
              return Token.ASSIGN_ADD;
          } else if ( this.matchChar('+') ) {
              return Token.INC;
          } else {
              return Token.ADD;
          }

      case 0x2D:  // '-'
          if ( this.matchChar('=') ) {
              c = Token.ASSIGN_SUB;
          } else if ( this.matchChar('-') ) {
              if ( !this.dirtyLine ) {
                  // treat HTML end-comment after possible whitespace
                  // after line start as comment-untill-eol
                  if ( this.matchChar('>')) {
                      this.skipLine();
                      continue retry;
                  }
              }
              c = Token.DEC;
          } else {
              c = Token.SUB;
          }
          this.dirtyLine = true;
          return c;

      default:
          parser.addError("msg.illegal.character");
          return Token.ERROR;
      }
  }
};



/**
* Parser calls the method when it gets / or /= in literal context.
*/
proto.readRegExp = function ( startToken )
{
  if ( startToken === Token.ASSIGN_DIV ) {
      // Miss-scanned /=
      this.stringBuffer = ["/="];
  } else if ( startToken === Token.DIV ) {
      this.stringBuffer = ["/"];
  } else {
      Kit.codeBug();
  }

  var c;
  while ( (c = this.getChar()) !== '/' ) {
      if ( c === '\n' || c === EOF_CHAR ) {
          this.ungetChar(c);
          throw this.parser.reportError("msg.unterminated.re.lit");
      }
      if ( c === '\\' ) {
          this.addToString(c);
          c = this.getChar();
      }
      this.addToString(c);
  }
  this.addToString("/");

  while ( isIdentifierPart(c = this.getChar()) ) {
      this.addToString(c);
  }
  this.ungetChar(c);

  this.string = this.getStringFromBuffer();
}


proto.isXMLAttribute = function ( )
{
  return this.xmlIsAttribute;
};

proto.getFirstXMLToken = function ( )
{
  this.xmlOpenTagsCount = 0;
  this.xmlIsAttribute   = false;
  this.xmlIsTagContent  = false;
  this.ungetChar('<');
  return this.getNextXMLToken();
};

proto.getNextXMLToken = function ( )
{
  this.stringBuffer = []; // remember the XML

  for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
      if ( this.xmlIsTagContent ) {
          switch ( c.charCodeAt(0) ) {
          case 0x3E:  // '>'
              this.addToString('>');
              this.xmlIsTagContent = false;
              this.xmlIsAttribute  = false;
              break;
          case 0x2F:  // '/'
              this.addToString('/');
              if ( this.matchChar('>') ) {
                  this.addToString('>');
                  this.xmlIsTagContent = false;
                  this.xmlOpenTagsCount--;
              }
              break;
          case 0x7B:  // '{'
              this.ungetChar('{');
              this.string = this.getStringFromBuffer();
              return Token.XML;
          case 0x27:  // "'"
          case 0x22:  // '"'
              this.addToString(c);
              if ( !this.readQuotedString(c) ) return Token.ERROR;
              break;
          case 0x3D:  // '='
              this.addToString('=');
              this.xmlIsAttribute = true;
              break;
          case 0x20:  // ' '
          case 0x09:  // '\t'
          // case 0x0D:  // '\r'  CR never comes here because of the implementation of getChar().
          case 0x0A:  // '\n'
              this.addToString(c);
              break;
          default:
              this.addToString(c);
              this.xmlIsAttribute = false;
              break;
          }

          if ( !this.xmlIsTagContent  &&  this.xmlOpenTagsCount === 0 ) {
              this.string = this.getStringFromBuffer();
              return Token.XMLEND;
          }
      } else {
          switch ( c.charCodeAt(0) ) {
          case 0x3C:  // '<'
              this.addToString('<');
              c = this.getChar();
              switch ( c.charCodeAt(0) ) {
              case 0x21:  // '!'
                  this.addToString('!');
                  c = this.getChar();
                  switch ( c.charCodeAt(0) ) {
                  case 0x2D:  // '-'
                      if ( this.getChar() === '-' ) {
                          this.addToString('--');
                          if ( !this.readXmlComment() ) return Token.ERROR;
                      } else {
                          this.parser.addError("msg.XML.bad.form");
                          return Token.ERROR;
                      }
                      break;
                  case 0x5B:  // '['
                      if ( this.getChar() === 'C' &&
                           this.getChar() === 'D' &&
                           this.getChar() === 'A' &&
                           this.getChar() === 'T' &&
                           this.getChar() === 'A' &&
                           this.getChar() === '['    )
                      {
                          this.addToString('[CDATA[');
                          if ( !this.readCDATA() ) return Token.ERROR;
                      } else {
                          this.parser.addError("msg.XML.bad.form");
                          return Token.ERROR;
                      }
                      break;
                  default:
                      this.ungetChar(c);
                      if( !this.readEntity() ) return Token.ERROR;
                      break;
                  }
                  break;
              case 0x3F:  // '?'
                  this.addToString('?');
                  if ( !this.readPI() ) return Token.ERROR;
                  break;
              case 0x2F:  // '/'
                  // End tag
                  this.addToString('/');
                  if ( this.xmlOpenTagsCount === 0 ) {
                      this.parser.addError("msg.XML.bad.form");
                      return Token.ERROR;
                  }
                  this.xmlIsTagContent = true;
                  this.xmlOpenTagsCount--;
                  break;
              default:
                  // Start tag
                  this.ungetChar(c);
                  this.xmlIsTagContent = true;
                  this.xmlOpenTagsCount++;
                  break;
              }
              break;
          case 0x7B:  // '{'
              this.ungetChar('{');
              this.string = this.getStringFromBuffer();
              return Token.XML;
          default:
              this.addToString(c);
              break;
          }
      }
  }

  this.parser.addError("msg.XML.bad.form");
  return Token.ERROR;
};

proto.readQuotedString = function ( quote )
{
  for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
      this.addToString(c);
      if ( c === quote ) return true;
  }
  parser.addError("msg.XML.bad.form");
  return false;
};

proto.readXmlComment = function ( )
{
  for ( var c=this.getChar();  c !== EOF_CHAR; ) {
      this.addToString(c);
      if ( c === '-'  &&  this.matchChar('-') ) {
          this.addToString('-');
          if ( this.matchChar('>') ) {
              this.addToString('>');
              return true;
          } else {
              // Strictly, XMLComment MUST NOT include the sequence "--".
              // So, if the program execution is here, the source is 
              // syntactically wrong, according to ECMA367. However, we 
              // allow the sequence here, so that our syntax is super-set 
              // of the specification.
              c = '-';
              continue;
          }
      }
      c = this.getChar();
  }
  this.parser.addError("msg.XML.bad.form");
  return false;
};

proto.readCDATA = function ( )
{
  for ( var c=this.getChar();  c !== EOF_CHAR; ) {
      this.addToString(c);
      if ( c === ']'  &&  this.matchChar(']') ) {
          this.addToString(']');
          if ( this.matchChar('>') ) {
              this.addToString('>');
              return true;
          } else {
              c = ']';
              continue;
          }
      }
      c = this.getChar();
  }
  this.parser.addError("msg.XML.bad.form");
  return false;
};

proto.readEntity = function ( )
{
  var declTags = 1;
  for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
      this.addToString(c);
      switch ( c ) {
      case '<':
          declTags++;
          break;
      case '>':
          declTags--;
          if ( declTags === 0 ) return true;
          break;
      }
  }
  this.parser.addError("msg.XML.bad.form");
  return false;
};

proto.readPI = function ( )
{
  for ( var c=this.getChar();  c !== EOF_CHAR;  c=this.getChar() ) {
      this.addToString(c);
      if ( c === '?'  &&  this.matchChar('>') ) {
          this.addToString('>');
          return true;
      }
  }
  this.parser.addError("msg.XML.bad.form");
  return false;
};


proto.getStringFromBuffer = function ( )
{
  return this.stringBuffer.join("");
};

proto.addToString = function ( /* variable arguments */ )
{
  this.stringBuffer.push.apply(this.stringBuffer, arguments);
};

proto.ungetChar = function ( c )
{
  // can not unread past across line boundary
  if ( this.ungetBuffer.length && this.ungetBuffer[this.ungetBuffer.length-1] == '\n') Kit.codeBug();
  this.ungetBuffer.push(c);
};

proto.matchChar = function ( test )
{
  var c = this.getChar();
  if ( c === test ) {
      return true;
  } else {
      this.ungetChar(c);
      return false;
  }
};

proto.peekChar = function ( )
{
  var c = this.getChar();
  this.ungetChar(c);
  return c;
};

proto.getChar = function ( )
{
  if ( this.ungetBuffer.length ) return this.ungetBuffer.pop();

  for ( ;; ) {
      if ( this.sourceCursor == this.sourceEnd ) {
          this.hitEOF = true;
          return EOF_CHAR;
      }
      var c = this.sourceString.charAt(this.sourceCursor++);

      if ( this.lineEndChar ) {
          if ( this.lineEndChar == '\r' && c == '\n') {
              this.lineEndChar = '\n';
              continue;
          }
          this.lineEndChar = undefined;
          this.lineStart   = this.sourceCursor - 1;
          this.lineno++;
      }

      if ( isLineTerminator(c) ) {
          this.lineEndChar = c;
          c = '\n';
      }
      if ( isFormatChar(c) ) {
          continue;
      }
      return c;
  }
};

proto.skipLine = function ( )
{
  // skip to end of line
  var c;
  while ((c=this.getChar()) != EOF_CHAR && c != '\n') { }
  this.ungetChar(c);
};

proto.getOffset = function ( )
{
  var n = this.sourceCursor - this.lineStart;
  if ( this.lineEndChar ) { --n; }
  return n;
};

proto.getLine = function ( )
{
  var lineEnd = this.sourceCursor;
  if ( this.lineEndChar ) {
      --lineEnd;
  } else {
      for (; lineEnd != this.sourceEnd; ++lineEnd) {
          var c = this.sourceString.charAt(lineEnd);
          if ( isLineTerminator(c) ) {
              break;
          }
      }
  }
  return this.sourceString.substring(this.lineStart, lineEnd);
};


          return {
              TokenStream: TokenStream
          };
      }();
  }
}.call(null) ) {
  this.Concurrent.Thread.Compiler.TokenStream = TokenStream;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Concurrent.Thread.Compiler.IntermediateLanguage || (typeof this.Concurrent.Thread.Compiler.IntermediateLanguage != 'object' && typeof this.Concurrent.Thread.Compiler.IntermediateLanguage != 'function') ) this.Concurrent.Thread.Compiler.IntermediateLanguage = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Function === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Function = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Block === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Block = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement = undefined;
  if ( this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement === undefined ) this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler.IntermediateLanguage ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Compiler.IntermediateLanguage';














function Function ( name, params, vars, body, start ) {
  this.name   = name;    // Identifier | Null
  this.params = params;  // [Identifier]
  this.vars   = vars;    // [Identifier]
  this.body   = body;    // <Block>
  this.start  = start;   // Block
}

Function.prototype.toString = function ( ) {
  return  [ "function ", this.name, "( ", this.params.join(", "), " ) {\n",
            "  var ", this.vars.join(", "), ";\n",
            this.body.join("\n").replace(/^/mg, "  "),
            "\n}" ].join("");
};



var block_id = 0;

function Block ( scopes, body, target, exception ) {
  this.id        = "label" + block_id++;
  this.scopes    = scopes;     // [Expression]
  this.body      = body;       // <Statement>
  this.target    = target;     // Block | "return" | "throw"
  this.exception = exception;  // Block | "return" | "throw"
}

var proto = Block.prototype;

proto.toString = function ( ) {
  Kit.codeBug('"toString" is not implemented for ', this.constructor);
};

proto.appendStatement = function ( /* variable arguments */ ) {
  var args = arguments;
  if ( this.body.isNil() ) {
      this.body = cons(arguments[0], this.body);
      args = Array.prototype.slice.call(arguments, 1, arguments.length);
  } else {
      adder(this.body).apply(null, args);
  }
};

proto.prependStatement = function ( /* variable arguments */ ) {
  for ( var i=arguments.length-1;  i >= 0;  i-- ) {
      this.body = cons(arguments[i], this.body);
  }
};


function stringify ( b ) {
  if ( b instanceof Block ) {
      return b.id;
  } else {
      return '"' + b + '"';
  }
}



function GotoBlock ( scopes, body, arg, target, exception ) {
  Block.call(this, scopes, body, target, exception);
  this.arg = arg;
}

var proto = GotoBlock.prototype = new Block();

proto.constructor = GotoBlock;

proto.toString = function ( ) {
  return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
           this.body.join("\n").replace(/^/mg, "  "), "\n",
           "  goto ", this.arg, " -> ", stringify(this.target), "\n",
           "}" ].join("");
};



function CallBlock ( scopes, body, this_val, func, args, target, exception ) {
  Block.call(this, scopes, body, target, exception);
  this.this_val  = this_val;   // Expression
  this.func      = func;       // Expression
  this.args      = args;       // [Expression]
}

var proto = CallBlock.prototype = new Block();

proto.constructor = CallBlock;

proto.toString = function ( ) {
  return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
           this.body.join("\n").replace(/^/mg, "  "), "\n",
           "  call ", this.this_val, ".", this.func, "(", this.args.join(", "), ") -> ", stringify(this.target), "\n",
           "}" ].join("");
};



function NewBlock ( scopes, body, func, args, target, exception ) {
  Block.call(this, scopes, body, target, exception);
  this.func      = func;       // Expression
  this.args      = args;       // [Expression]
}

var proto = NewBlock.prototype = new Block();

proto.constructor = NewBlock;

proto.toString = function ( ) {
  return [ this.id, "([", this.scopes.join(", "), "], ", stringify(this.exception), "): {\n",
           this.body.join("\n").replace(/^/mg, "  "), "\n",
           "  new ", this.func, "(", this.args.join(", "), ") -> ", stringify(this.target), "\n",
           "}" ].join("");
};




function Statement ( ) {
  // This is kind of interface.
}

Statement.prototype.toString = function ( ) {
  Kit.codeBug('"toString" is not implemented for ', this.constructor);
};



function ExpStatement ( e ) {
  this.exp = e;  // Expression
}

var proto = ExpStatement.prototype = new Statement();

proto.constructor = ExpStatement;

proto.toString = function ( ) {
  return this.exp + ";";
};



function CondStatement ( c, t ) {
  this.cond   = c;  // Expression
  this.target = t;  // Block
}

var proto = CondStatement.prototype = new Statement();

proto.constructor = CondStatement;

proto.toString = function ( ) {
  return [ "if ", this.cond, " -> ", stringify(this.target), ";" ].join("");
};



function RecvStatement ( a ) {
  this.assignee = a;  // Identifier | DotAccessor | BracketAccessor
}

var proto = RecvStatement.prototype = new Statement();

proto.constructor = RecvStatement;

proto.toString = function ( ) {
  return [ "recv ", this.assignee, ";" ].join("");
};



function EnumStatement ( e, a ) {
  this.exp      = e;  // Expression
  this.assignee = a;  // Identifier | DotAccessor | BracketAccessor
}

var proto = EnumStatement.prototype = new Statement();

proto.constructor = EnumStatement;

proto.toString = function ( ) {
  return [ "enum ", this.assignee, " <- ", this.exp, ";" ].join("");
};

          return {
              Block: Block, RecvStatement: RecvStatement, GotoBlock: GotoBlock, Function: Function, NewBlock: NewBlock, ExpStatement: ExpStatement, CallBlock: CallBlock, EnumStatement: EnumStatement, Statement: Statement, CondStatement: CondStatement
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.IntermediateLanguage.Block = Block;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.RecvStatement = RecvStatement;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.GotoBlock = GotoBlock;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.Function = Function;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.NewBlock = NewBlock;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.ExpStatement = ExpStatement;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.CallBlock = CallBlock;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.EnumStatement = EnumStatement;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.Statement = Statement;
  this.Concurrent.Thread.Compiler.IntermediateLanguage.CondStatement = CondStatement;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.CssConvert === undefined ) this.Concurrent.Thread.Compiler.CssConvert = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';












var Css = "Concurrent.Thread.Compiler.CssConvert";



function CssConvert ( func ) {
  return func[Css]();
}


Statement.prototype[Css] = function ( ) {
  Kit.codeBug("unimplemented '" + Css + "' method for: " + this);
};

EmptyStatement.prototype[Css] = function ( ) {
  return this;
};

Block.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new Block(this.labels, head.cdr, this.lineno, this.source);
};

ExpStatement.prototype[Css] = function ( ) {
  return new ExpStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

VarStatement.prototype[Css] = function ( ) {
  var decls = [];
  for ( var i=0;  i < this.decls.length;  i++ ) {
      decls[i] = {
          id : this.decls[i].id,
          exp: this.decls[i].exp ? this.decls[i].exp[Css]() : null
      };
  }
  return new VarStatement(this.labels, decls, this.lineno, this.source);
};

IfStatement.prototype[Css] = function ( ) {
  return new IfStatement(this.labels, this.cond[Css](), this.body[Css](), this.lineno, this.source);
};

IfElseStatement.prototype[Css] = function ( ) {
  return new IfElseStatement(this.labels, this.cond[Css](), this.tbody[Css](), this.fbody[Css](), this.lineno, this.source);
};

DoWhileStatement.prototype[Css] = function ( ) {
  return new DoWhileStatement(this.labels, this.body[Css](), this.cond[Css](), this.lineno, this.source);
};

WhileStatement.prototype[Css] = function ( ) {
  return new WhileStatement(this.labels, this.cond[Css](), this.body[Css](), this.lineno, this.source);
};

ForStatement.prototype[Css] = function ( ) {
  return new ForStatement(
      this.labels,
      this.init ? this.init[Css]() : null,
      this.cond ? this.cond[Css]() : null,
      this.incr ? this.incr[Css]() : null,
      this.body[Css](),
      this.lineno,
      this.source
  );
};

ForVarStatement.prototype[Css] = function ( ) {
  var decls = [];
  for ( var i=0;  i < this.decls.length;  i++ ) {
      decls[i] = {
          id : this.decls[i].id,
          exp: this.decls[i].exp ? this.decls[i].exp[Css]() : null
      };
  }
  return new ForVarStatement(
      this.labels,
      decls,
      this.cond ? this.cond[Css]() : null,
      this.incr ? this.incr[Css]() : null,
      this.body[Css](),
      this.lineno,
      this.source
  );
};

ForInStatement.prototype[Css] = function ( ) {
  return new ForInStatement(this.labels, this.lhs[Css](), this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForInVarStatement.prototype[Css] = function ( ) {
  var decl = {
      id : this.decl.id,
      exp: this.decl.exp ? this.decl.exp[Css]() : null
  };
  return new ForInVarStatement(this.labels, decl, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForEachStatement.prototype[Css] = function ( ) {
  return new ForEachStatement(this.labels, this.lhs[Css](), this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ForEachVarStatement.prototype[Css] = function ( ) {
  var decl = {
      id : this.decl.id,
      exp: this.decl.exp ? this.decl.exp[Css]() : null
  };
  return new ForEachVarStatement(this.labels, decl, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

ContinueStatement.prototype[Css] = function ( ) {
  return this;
};

BreakStatement.prototype[Css] = function ( ) {
  return this;
};

ReturnStatement.prototype[Css] = function ( ) {
  if ( !this.exp ) return this;
  return new ReturnStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

WithStatement.prototype[Css] = function ( ) {
  return new WithStatement(this.labels, this.exp[Css](), this.body[Css](), this.lineno, this.source);
};

SwitchStatement.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.clauses;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new SwitchStatement(this.labels, this.exp[Css](), head.cdr, this.lineno, this.source);
};

CaseClause.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new CaseClause(this.exp[Css](), head.cdr, this.lineno, this.source);
};

DefaultClause.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new DefaultClause(head.cdr, this.lineno, this.source);
};

ThrowStatement.prototype[Css] = function ( ) {
  return new ThrowStatement(this.labels, this.exp[Css](), this.lineno, this.source);
};

TryCatchStatement.prototype[Css] = function ( ) {
  return new TryCatchStatement(this.labels, this.tryBlock[Css](), this.variable, this.catchBlock[Css](), this.lineno, this.source);
};

TryFinallyStatement.prototype[Css] = function ( ) {
  return new TryFinallyStatement(this.labels, this.tryBlock[Css](), this.finallyBlock[Css](), this.lineno, this.source);
};

TryCatchFinallyStatement.prototype[Css] = function ( ) {
  return new TryCatchFinallyStatement(this.labels, this.tryBlock[Css](), this.variable, this.catchBlock[Css](), this.finallyBlock[Css](), this.lineno, this.source);
};

TryCatchListStatement.prototype[Css] = function ( ) {
  if ( this.catchList.isNil() ) {  // no more catch-guard
      var block = this.tryBlock[Css]();
      block.labels = this.labels;
      return block;
  } else if ( this.catchList.car.cond ) {  // one or more qualified catch-guard
      var guard = this.catchList.car;
      return new TryCatchStatement(
          this.labels,
          this.tryBlock[Css](),
          guard.variable,
          new Block([], list(
              new IfElseStatement(
                  [],
                  guard.cond[Css](),
                  guard.block[Css](),
                  (new TryCatchListStatement(
                      [],
                      new Block([], list(new ThrowStatement([], guard.variable))),
                      this.catchList.cdr,
                      this.catchList.cdr.lineno, this.cdr.cdr.source
                  ))[Css](),
                  guard.lineno, guard.source
              )
          ))
      );
  } else {  // (only one) default catch-guard
      var guard = this.catchList.car;
      return new TryCatchStatement(this.labels, this.tryBlock[Css](), guard.variable, guard.block[Css](), this.lineno, this.source);
  }
};

TryCatchListFinallyStatement.prototype[Css] = function ( ) {
  return new TryFinallyStatement(
      this.labels,
      new Block([], list(
          (new TryCatchListStatement([],
              this.tryBlock,
              this.catchList,
              this.lineno,
              this.source
          ))[Css]()
      ), this.lineno, this.source),
      this.finallyBlock[Css](),
      this.lineno, this.source
  );
};

FunctionDeclaration.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new FunctionDeclaration(this.labels, this.name, this.params, head.cdr, this.lineno, this.source);
};



Expression.prototype[Css] = Statement.prototype[Css];

UnaryExpression.prototype[Css] = function ( ) {
  return new this.constructor( this.exp[Css]() );
};

BinaryExpression.prototype[Css] = function ( ) {
  return new this.constructor(this.left[Css](), this.right[Css]());
};

Literal.prototype[Css]        = 
Identifier.prototype[Css]     = 
ThisExpression.prototype[Css] = 
Elision.prototype[Css]        = function ( ) {
  return this;
};

ArrayInitializer.prototype[Css] = function ( ) {
  var elems = [];
  for ( var i=0;  i < this.elems.length;  i++ ) {
      elems[i] = this.elems[i][Css]();
  }
  return new ArrayInitializer(elems);
};

ObjectInitializer.prototype[Css] = function ( ) {
  var pairs = [];
  for ( var i=0;  i < this.pairs.length;  i++ ) {
      pairs[i] = {prop:this.pairs[i].prop, exp:this.pairs[i].exp[Css]()};
  }
  return new ObjectInitializer(pairs);
};

FunctionExpression.prototype[Css] = function ( ) {
  var head = last = cons(null, nil());
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      last = last.cdr = cons(c.car[Css](), last.cdr);
  }
  return new FunctionExpression(this.name, this.params, head.cdr);
};

DotAccessor.prototype[Css] = function ( ) {
  return new DotAccessor(this.base[Css](), this.prop);
};

NewExpression.prototype[Css]  =
CallExpression.prototype[Css] = function ( ) {
  var args = [];
  for ( var i=0;  i < this.args.length;  i++ ) {
      args[i] = this.args[i][Css]();
  }
  return new this.constructor(this.func[Css](), args);
};

ConditionalExpression.prototype[Css] = function ( ) {
  return new ConditionalExpression(this.cond[Css](), this.texp[Css](), this.fexp[Css]());
};

          return {
              CssConvert: CssConvert
          };
      }();
  }
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CssConvert = CssConvert;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.Parser === undefined ) this.Concurrent.Thread.Compiler.Parser = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Data ) {
with ( Data.Error ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Rhino code, released
* May 6, 1999.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1997-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Mike Ang
*   Igor Bukanov
*   Yuh-Ruey Chen
*   Ethan Hugg
*   Terry Lucas
*   Mike McCabe
*   Milen Nankov
*   Daisuke Maki
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License Version 2 or later (the "GPL"), in which
* case the provisions of the GPL are applicable instead of those above. If
* you wish to allow use of your version of this file only under the terms of
* the GPL and not to allow others to use your version of this file under the
* MPL, indicate your decision by deleting the provisions above and replacing
* them with the notice and other provisions required by the GPL. If you do
* not delete the provisions above, a recipient may use your version of this
* file under either the MPL or the GPL.
*
* ***** END LICENSE BLOCK ***** */

/**
* This file is based on the file Parser.java in Rhino 1.6R5.
*/





NAMESPACE = 'Concurrent.Thread.Compiler';





















// TokenInformation flags : flaggedTokenBuffer stores them together
// with token type
var CLEAR_TI_MASK  = 0xFFFF;   // mask to clear token information bits
var TI_AFTER_EOL   = 1 << 16;  // first token of the source line
var TI_CHECK_LABEL = 1 << 17;  // indicates to check for label


// Exception to unwind
var ParserException = Exception.extend(
  function($super, message){ $super(message); },
  { name: NAMESPACE + ".ParserException" }
);

// Exception to return statement-label
function LabelException ( label ) {
  this.label = label;  // Identifier
}


// default error reporter
var defaultReporter = new ErrorReporter();
defaultReporter.error = function ( message, line, lineSource, lineOffset ) {
  throw new SyntaxError("(" + line + ", " + lineOffset + "): " + message + "\nline: " + lineSource);
};



function Parser ( errorReporter )
{
  this.errorReporter       = errorReporter instanceof ErrorReporter
                               ?  errorReporter  :  defaultReporter;
  this.ts                  = undefined;  // TokenStream
  this.source              = undefined;  // String       # file-name, URL, ...etc
  this.flaggedTokenBuffer  = null;       // Stack
  this.syntaxErrorCount    = 0;
  this.nestingOfFunction   = 0;
  // The following are per function variables and should be saved/restored
  // during function parsing.
  this.nestingOfLoop   = 0;
  this.nestingOfSwitch = 0;
  this.allLabelSet     = null;  // contains all labels in current scope
  this.loopLabelSet    = null;  // contains only labels qualifying IterationStatement in current scope
}

var proto = Parser.prototype;


proto.getMessage = function ( messageId  /* optional args */ )
{
  //!! fake implementation
  return messageId;
};

proto.addWarning = function ( messageId  /* optional args */ )
{
  this.errorReporter.warning(this.getMessage.apply(this, arguments),
                             this.ts.getLineno()                   ,
                             this.ts.getLine()                     ,
                             this.ts.getOffset()                   );
};

proto.addError = function ( messageId  /* optional args */ )
{
  ++this.syntaxErrorCount;
  this.errorReporter.error(this.getMessage.apply(this, arguments),
                           this.ts.getLineno()                   ,
                           this.ts.getLine()                     ,
                           this.ts.getOffset()                   );
};

proto.reportError = function ( messageId  /* optional args */ )
{
  this.addError.apply(this, arguments);
  // Throw a ParserException exception to unwind the recursive descent
  // parse.
  throw new ParserException();
};


proto.peekToken = function ( )
{
  var tt;
  if ( this.flaggedTokenBuffer.isEmpty() ) {
      tt = this.ts.getToken();
      if ( tt === Token.EOL ) {
          do {
              tt = this.ts.getToken();
          } while ( tt === Token.EOL );
          tt |= TI_AFTER_EOL;
      }
      this.flaggedTokenBuffer.push(tt);
  } else {
      tt = this.flaggedTokenBuffer.peek();
  }
  return tt & CLEAR_TI_MASK;
};

proto.peekFlaggedToken = function ( )
{
  this.peekToken();
  return this.flaggedTokenBuffer.peek();
};

proto.consumeToken = function ( )
{
  this.flaggedTokenBuffer.pop();
};

proto.nextToken = function ( )
{
  var tt = this.peekToken();
  this.consumeToken();
  return tt;
};

proto.nextFlaggedToken = function ( )
{
  this.peekToken();
  var ttFlagged = this.flaggedTokenBuffer.peek();
  this.consumeToken();
  return ttFlagged;
};

proto.matchToken = function ( toMatch )
{
  if ( this.peekToken() !== toMatch ) return false;
  this.consumeToken();
  return true;
};

proto.peekTokenOrEOL = function ( )
{
  var tt = this.peekToken();
  // Check for last peeked token flags
  if ( this.flaggedTokenBuffer.peek() & TI_AFTER_EOL ) return Token.EOL;
  return tt;
};

// Since we need to backtrack to properly parse "default xml namespace"
// in switch-statement.
proto.ungetToken = function ( token )
{
  this.flaggedTokenBuffer.push(token);
};

proto.setCheckForLabel = function ( )
{
  var tt = this.flaggedTokenBuffer.pop();
  if ( (tt & CLEAR_TI_MASK) !== Token.NAME ) throw Kit.codeBug();
  this.flaggedTokenBuffer.push(tt | TI_CHECK_LABEL);
};

proto.mustMatchToken = function ( toMatch, messageId  /* optional args */ )
{
  if ( !this.matchToken(toMatch) ) {
      var args = [];
      for ( var i=1;  i < arguments.length;  i++ ) args.push(arguments[i]);
      this.reportError.apply(this, args);
  }
};

proto.eof = function ( )
{
  return this.ts.eof();
};

proto.insideFunction = function ( )
{
  return this.nestingOfFunction !== 0;
};

proto.insideLoop = function ( )
{
  return this.nestingOfLoop !== 0;
};

proto.enterLoop = function ( labels )
{
  for ( var i=0;  i < labels.length;  i++ ) this.loopLabelSet.add(labels[i]);
  this.nestingOfLoop++;
};

proto.exitLoop = function ( labels )
{
  for ( var i=0;  i < labels.length;  i++ ) this.loopLabelSet.remove(labels[i]);
  this.nestingOfLoop--;
};


proto.parse = function ( sourceString, lineno, source )
{
  this.ts     = new TokenStream(this, sourceString, lineno);
  this.source = source;  // optional
  this.flaggedTokenBuffer = new Stack();
  this.syntaxErrorCount   = 0;
  this.nestingOfFunction  = 0;
  this.nestingOfLoop      = 0;
  this.nestingOfSwitch    = 0;
  this.allLabelSet        = new IdentifierSet();
  this.loopLabelSet       = new IdentifierSet();

  try {
      var body = this.statements();
      this.mustMatchToken(Token.EOF, "msg.syntax");
  } catch ( e ) {
      if ( e instanceof ParserException ) {
          // Ignore it.
      } else {
          // Maybe stack overflow.
          //!!fake implementation
          throw e;
      }
  }

  if ( this.syntaxErrorCount ) {
      var msg = "msg.got.syntax.errors";
      this.addError(msg);
      throw new SyntaxError(this.getMessage("msg.got.syntax.errors"));
  }

  this.ts = null; // It helps GC
  return body;
};


proto.statements = function ( )
{
  var head, cell;
  cell = head = cons(null, nil());
  bodyLoop: for (;;) {
      var n;
      switch ( this.peekToken() ) {
        case Token.ERROR:
        case Token.EOF:
        case Token.RC:
          break bodyLoop;
        case Token.FUNCTION:  // save the stack
          this.consumeToken();
          n = this.functionDecl([]);
          break;
        default:
          n = this.statement();
          break;
      }
      cell = cell.cdr = cons(n, cell.cdr);
  }
  return head.cdr;
};


proto.functionDecl = function ( labels )
{
  var baseLineno = this.ts.getLineno();  // line number where source starts
  this.mustMatchToken(Token.NAME, "msg.no.func.name");
  var name   = new Identifier(this.ts.getString());
  var params = this.parameterList();
  var body   = this.functionBody();
  return new FunctionDeclaration(labels, name, params, body, baseLineno, this.source);
};

proto.functionExpr = function ( )
{
  var name = null;
  if ( this.matchToken(Token.NAME) ) name = new Identifier(this.ts.getString());
  var params = this.parameterList();
  var body   = this.functionBody();
  return new FunctionExpression(name, params, body);
};

proto.parameterList = function ( )
{
  this.mustMatchToken(Token.LP, "msg.no.paren.parms");
  if ( this.matchToken(Token.RP) ) return [];
  var params = [];
  var exists = new IdentifierSet();
  do {
      this.mustMatchToken(Token.NAME, "msg.no.parm");
      var p = new Identifier(this.ts.getString());
      if ( exists.contains(p) ) this.addWarning("msg.dup.parms", s);
      params.push(p);
      exists.add(p);
  } while ( this.matchToken(Token.COMMA) );
  this.mustMatchToken(Token.RP, "msg.no.paren.after.parms");
  return params;
};

proto.functionBody = function ( )
{
  this.mustMatchToken(Token.LC, "msg.no.brace.body");
  
  var saveAllLabel  = this.allLabelSet;
  var saveLoopLabel = this.loopLabelSet;
  var saveLoop      = this.nestingOfLoop;
  var saveSwitch    = this.nestingOfSwitch;
  this.allLabelSet  = new IdentifierSet();
  this.loopLabelSet = new IdentifierSet();
  this.nestingOfLoop   = 0;
  this.nestingOfSwitch = 0;
  this.nestingOfFunction++;
  try {
      var body = this.statements();
  } catch ( e ) {
      if ( e instanceof ParserException ) {
          // Ignore it
      } else {
          throw e;
      }
  } finally {
      this.allLabelSet     = saveAllLabel;
      this.loopLabelSet    = saveLoopLabel;
      this.nestingOfLoop   = saveLoop;
      this.nestingOfSwitch = saveSwitch;
      this.nestingOfFunction--;
  }

  this.mustMatchToken(Token.RC, "msg.no.brace.after.body");
  return body;
};


proto.statement = function ( )
{
  try {
      var n = this.statementHelper([]);
      if ( n != null ) return n;
  } catch ( e ) {
      if ( e instanceof ParserException ) {
          // Ignore it.
      } else {
          throw e;
      }
  }

  // skip to end of statement
  guessingStatementEnd: for (;;) {
      var tt = this.peekTokenOrEOL();
      this.consumeToken();
      switch ( tt ) {
        case Token.ERROR:
        case Token.EOF:
        case Token.EOL:
        case Token.SEMI:
          break guessingStatementEnd;
      }
  }
  return null;
};

proto.statementHelper = function ( labels )
{
  var statement = null;
  switch ( this.peekToken() ) {
    case Token.IF: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      var cond   = this.condition();
      var tstat  = this.statement();
      if ( this.matchToken(Token.ELSE) ) {
          return new IfElseStatement(labels, cond, tstat, this.statement(), lineno, this.source);
      } else {
          return new IfStatement(labels, cond, tstat, lineno, this.source);
      }
    }

    case Token.SWITCH: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      this.mustMatchToken(Token.LP, "msg.no.paren.switch");
      var exp = this.expr(false);
      this.mustMatchToken(Token.RP, "msg.no.paren.after.switch");
      this.mustMatchToken(Token.LC, "msg.no.brace.switch");
      var switchStatement = new SwitchStatement(labels, exp, nil(), lineno, this.source);
      var clauses = cons(nil(), nil());
      var last = clauses;
      this.nestingOfSwitch++;
      try {
          var hasDefault = false;
          switchLoop: for (;;) {
              var lineno = this.ts.getLineno();
              var caseExpression;
              switch ( this.nextToken() ) {
                case Token.RC:
                  break switchLoop;
                case Token.CASE:
                  caseExpression = this.expr(false);
                  this.mustMatchToken(Token.COLON, "msg.no.colon.case");
                  break;
                case Token.DEFAULT:
                  if ( hasDefault ) this.reportError("msg.double.switch.default");
                  hasDefault     = true;
                  caseExpression = null;
                  this.mustMatchToken(Token.COLON, "msg.no.colon.case");
                  break;
                default:
                  this.reportError("msg.bad.switch");
                  break switchLoop;
              }
              var c = caseExpression
                        ?  new CaseClause(caseExpression, this.statementsInSwitch(), lineno, this.source)
                        :  new DefaultClause(this.statementsInSwitch(), lineno, this.source);
              last = last.cdr = cons(c, last.cdr);
          }
      } finally {
          this.nestingOfSwitch--;
      }
      switchStatement.clauses = clauses.cdr;
      return switchStatement;
    }

    case Token.WHILE: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      this.enterLoop(labels);
      try {
          return new WhileStatement(labels, this.condition(), this.statement(), lineno, this.source);
      } finally {
          this.exitLoop(labels);
      }
    }

    case Token.DO: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      this.enterLoop(labels);
      try {
          var body = this.statement();
      } finally {
          this.exitLoop(labels);
      }
      this.mustMatchToken(Token.WHILE, "msg.no.while.do");
      var cond = this.condition();
      // Always auto-insert semicon to follow SpiderMonkey:
      // It is required by EMAScript but is ignored by the rest of
      // world, see bug 238945
      this.matchToken(Token.SEMI);
      return new DoWhileStatement(labels, body, cond, lineno, this.source);
    }

    case Token.FOR: {
      this.consumeToken();
      var lineno = this.ts.getLineno();

      var init;  // init is also foo in 'foo in Object'
      var cond;  // cond is also object in 'foo in Object'
      var incr = null;
      var body;

      var isForEach = false;
      var isForIn   = false;
      var isVar     = false;

      // See if this is a for each () instead of just a for ()
      if ( this.matchToken(Token.NAME) ) {
          if ( this.ts.getString() === "each" ) {
              isForEach = true;
          } else {
              this.reportError("msg.no.paren.for");
          }
      }

      this.mustMatchToken(Token.LP, "msg.no.paren.for");

      var tt = this.peekToken();
      if ( tt === Token.SEMI ) {
          init = null;
      } else {
          if ( tt === Token.VAR ) {
              // set init to a var list or initial
              this.consumeToken();    // consume the 'var' token
              init  = this.variables(true);
              isVar = true;
          }
          else {
              init = this.expr(true);
          }
      }

      if ( this.matchToken(Token.IN) ) {
          isForIn = true;
          // 'cond' is the object over which we're iterating
          cond = this.expr(false);
      } else {  // ordinary for loop
          this.mustMatchToken(Token.SEMI, "msg.no.semi.for");
          if ( this.peekToken() === Token.SEMI ) {
              // no loop condition
              cond = null;
          } else {
              cond = this.expr(false);
          }

          this.mustMatchToken(Token.SEMI, "msg.no.semi.for.cond");
          if ( this.peekToken() === Token.RP ) {
              incr = null;
          } else {
              incr = this.expr(false);
          }
      }

      this.mustMatchToken(Token.RP, "msg.no.paren.for.ctrl");

      this.enterLoop(labels);
      try {
          body = this.statement();
      } finally {
          this.exitLoop(labels);
      }
      
      if ( !isForIn ) {
          // Although SpiderMonkey doesn't allow "for each ( ...; ...; ... )",
          // Rhino1.6R5 allowed it. We follow Rhino's position here.
          if ( isVar ) return new ForVarStatement(labels, init, cond, incr, body, lineno, this.source);
          else         return new ForStatement(labels, init, cond, incr, body, lineno, this.source);
      } else {
          if ( isVar ) {
              // Check if init (var declarations) contains only one.
              if ( init.length != 1 ) this.reportError("msg.mult.index");
              if ( isForEach ) return new ForEachVarStatement(labels, init[0], cond, body, lineno, this.source);
              else             return new ForInVarStatement(labels, init[0], cond, body, lineno, this.source);
          } else {
              // Check if init (an expression left-hand-side of "in") has lvalue.
              if ( !init.hasLvalue() ) this.reportError("msg.bad.for.in.lhs");
              if ( isForEach ) return new ForEachStatement(labels, init, cond, body, lineno, this.source);
              else             return new ForInStatement(labels, init, cond, body, lineno, this.source);
          }
      }
    }

    case Token.TRY: {
      this.consumeToken();
      var lineno = this.ts.getLineno();

      // Although ECMA262-3 requires a block here, Rhino1.6R5 allows any kind of statement.
      // We follow Rhino's style, but issue warning when a statement is not a block.
      var tryBlock = this.statement();
      if ( !(tryBlock instanceof Block) ) {
          this.addWarning("msg.no.brace.tryblock");
          tryBlock = new Block([], cons(tryBlock, nil()), tryBlock.lineno, tryBlock.source);
      }

      var catchList;
      var cell = catchList = cons(null, nil());
      var sawDefaultCatch = false;
      var peek = this.peekToken();
      if ( peek === Token.CATCH ) {
          while ( this.matchToken(Token.CATCH) ) {
              if ( sawDefaultCatch ) this.reportError("msg.catch.unreachable");
              var line = this.ts.getLineno();
              this.mustMatchToken(Token.LP, "msg.no.paren.catch");
              this.mustMatchToken(Token.NAME, "msg.bad.catchcond");
              var variable = new Identifier(this.ts.getString());

              var cond = null;
              if ( this.matchToken(Token.IF) ) {
                  cond = this.expr(false);
              } else {
                  sawDefaultCatch = true;
              }

              this.mustMatchToken(Token.RP, "msg.bad.catchcond");
              this.mustMatchToken(Token.LC, "msg.no.brace.catchblock");
              var block = new Block([], this.statements(), line, this.source);
              this.mustMatchToken(Token.RC, "msg.no.brace.after.body");

              var clause = new CatchGuard(variable, cond, block, line, this.source);
              cell = cell.cdr = cons(clause, cell.cdr);
          }
      } else if ( peek !== Token.FINALLY ) {
          this.mustMatchToken(Token.FINALLY, "msg.try.no.catchfinally");
      }
      catchList = catchList.cdr;

      var finallyBlock = null;
      if ( this.matchToken(Token.FINALLY) ) {
          // Rhino also allows any kind of statement here.
          finallyBlock = this.statement();
          if ( !(finallyBlock instanceof Block) ) {
              this.addWarning("msg.no.brace.finallyblock");
              finallyBlock = new Block([], cons(finallyBlock, nil()), finallyBlock.lineno, finallyBlock.source);
          }
      }

      return finallyBlock
               ? new TryCatchListFinallyStatement(labels, tryBlock, catchList, finallyBlock, lineno, this.source)
               : new TryCatchListStatement(labels, tryBlock, catchList, lineno, this.source);
    }

    case Token.THROW: {
      this.consumeToken();
      if ( this.peekTokenOrEOL() === Token.EOL ) {
          // ECMAScript does not allow new lines before throw expression,
          // see bug 256617
          this.reportError("msg.bad.throw.eol");
      }

      var lineno = this.ts.getLineno();
      statement = new ThrowStatement(labels, this.expr(false), lineno, this.source);
      break;
    }

    case Token.BREAK: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      var target = this.matchJumpLabelName(Token.BREAK);
      if ( target == null ) {
          if ( !this.nestingOfLoop && !this.nestingOfSwitch ) this.reportError("msg.bad.break");
      }
      statement = new BreakStatement(labels, target, lineno, this.source);
      break;
    }

    case Token.CONTINUE: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      var target = this.matchJumpLabelName(Token.CONTINUE);
      if ( target == null ) {
          if ( !this.nestingOfLoop ) reportError("msg.continue.outside");
      }
      statement = new ContinueStatement(labels, target, lineno, this.source);
      break;
    }

    case Token.WITH: {
      this.consumeToken();
      var lineno = this.ts.getLineno();
      this.mustMatchToken(Token.LP, "msg.no.paren.with");
      var exp = this.expr(false);
      this.mustMatchToken(Token.RP, "msg.no.paren.after.with");
      var body = this.statement();
      return new WithStatement(labels, exp, body, lineno, this.source);
    }

    case Token.VAR: {
      this.consumeToken();
      statement = new VarStatement(labels, this.variables(false), lineno, this.source);
      break;
    }

    case Token.RETURN: {
      if ( !this.insideFunction() ) this.reportError("msg.bad.return");
      this.consumeToken();
      var lineno = this.ts.getLineno();
      var exp;
      /* This is ugly, but we don't want to require a semicolon. */
      switch ( this.peekTokenOrEOL() ) {
        case Token.SEMI:
        case Token.RC:
        case Token.EOF:
        case Token.EOL:
        case Token.ERROR:
          exp = null;
          break;
        default:
          exp = this.expr(false);
      }
      statement = new ReturnStatement(labels, exp, lineno, this.source);
      break;
    }

    case Token.LC:
      this.consumeToken();
      var block = new Block(labels, this.statements(), lineno, this.source);
      this.mustMatchToken(Token.RC, "msg.no.brace.block");
      return block;

    case Token.ERROR:
      // Fall thru, to have a node for error recovery to work on
    case Token.SEMI:
      this.consumeToken();
      return new EmptyStatement(labels, lineno, this.source);

    case Token.FUNCTION: {
      this.consumeToken();
      return this.functionDecl(labels);
    }

    case Token.DEFAULT: {
      this.consumeToken();
      this.reportError("msg.XML.not.available");
    }

    case Token.NAME: {
      var lineno = this.ts.getLineno();
      this.setCheckForLabel();
      try {
          statement = new ExpStatement(labels, this.expr(false), lineno, this.source);
      } catch ( e ) {
          if ( e instanceof LabelException ) {
              // Label found!
              if ( this.allLabelSet.contains(e.label) ) this.reportError("msg.dup.label");
              this.allLabelSet.add(e.label);
              labels.push(e.label);
              try {
                  statement = this.statementHelper(labels);
              } finally {
                  this.allLabelSet.remove(e.label);
              }
              return statement;
          } else {
              throw e;
          }
      }
      break;
    }

    default: {
      var lineno = this.ts.getLineno();
      statement = new ExpStatement(labels, this.expr(false), lineno, this.source);
      break;
    }
  }

  switch ( this.peekTokenOrEOL() ) {
    case Token.SEMI:
      // Consume ';' as a part of statement
      this.consumeToken();
      break;
    case Token.ERROR:
    case Token.EOF:
    case Token.EOL:
    case Token.RC:
      // Autoinsert ;
      break;
    default:
      // Report error if no EOL or autoinsert ; otherwise
      this.reportError("msg.no.semi.stmt");
  }

  return statement;
};

proto.condition = function ( )
{
  this.mustMatchToken(Token.LP, "msg.no.paren.cond");
  var exp = this.expr(false);
  this.mustMatchToken(Token.RP, "msg.no.paren.after.cond");
  if ( exp instanceof SimpleAssignExpression ) this.addWarning("msg.assign.cond");
  return exp;
};

// match a NAME; return null if no match.
proto.matchJumpLabelName = function ( token )
{
  if ( this.peekTokenOrEOL() !== Token.NAME ) return null;
  var label = new Identifier(this.ts.getString());
  this.consumeToken();
  switch ( token ) {
    case Token.CONTINUE:
      if ( !this.loopLabelSet.contains(label) ) {
          this.reportError("msg.undef.label");
      }
      break;
    case Token.BREAK:
      if ( !this.allLabelSet.contains(label) ) {
          this.reportError("msg.undef.label");
      }
      break;
    default:
      throw Kit.codeBug();
  }
  return label;
};

proto.statementsInSwitch = function ( )
{
  var head, cell;
  head = cell = cons(null, nil());
  clauseLoop: for (;;) {
      switch ( this.peekToken() ) {
        case Token.ERROR:
        case Token.EOF:
        case Token.RC:
        case Token.CASE:
          break clauseLoop;
        case Token.DEFAULT:
          this.consumeToken();
          var tt = this.peekToken();
          this.ungetToken(Token.DEFAULT);
          if ( tt === Token.COLON ) break clauseLoop;
          // fall thru
        default:
          cell = cell.cdr = cons(this.statement(), cell.cdr);
      }
  }
  return head.cdr;
};

proto.variables = function ( inForInit )
{
  var decls = [];
  for (;;) {
      this.mustMatchToken(Token.NAME, "msg.bad.var");
      var name = new Identifier(this.ts.getString());
      var init = this.matchToken(Token.ASSIGN)
                   ?  this.assignExpr(inForInit)
                   :  null;
      decls.push({id: name, exp: init});
      if ( !this.matchToken(Token.COMMA) ) break;
  }
  return decls;
};


proto.expr = function ( inForInit )
{
  var exp = this.assignExpr(inForInit);
  while ( this.matchToken(Token.COMMA) ) {
      exp = new CommaExpression(exp, this.assignExpr(inForInit));
  }
  return exp;
};


proto.assignExpr = function ( inForInit )
{
  var exp = this.condExpr(inForInit);
  var tt  = this.peekToken();
  if ( tt < Token.FIRST_ASSIGN || Token.LAST_ASSIGN < tt ) return exp;

  if ( !exp.hasLvalue() ) this.reportError("msg.bad.assign.left");

  switch ( this.nextToken() ) {
    case Token.ASSIGN:
      return new SimpleAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_BITOR:
      return new BitOrAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_BITXOR:
      return new BitXorAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_BITAND:
      return new BitAndAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_LSH:
      return new LShiftAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_RSH:
      return new RShiftAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_URSH:
      return new URShiftAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_ADD:
      return new AddAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_SUB:
      return new SubAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_MUL:
      return new MulAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_DIV:
      return new DivAssignExpression(exp, this.assignExpr(inForInit));
    case Token.ASSIGN_MOD:
      return new ModAssignExpression(exp, this.assignExpr(inForInit));
    default:
      throw Kit.codeBug();
  }
};


proto.condExpr = function ( inForInit )
{
  var exp = this.orExpr(inForInit);
  if ( !this.matchToken(Token.HOOK) ) return exp;
  var ifTrue = this.assignExpr(false);
  this.mustMatchToken(Token.COLON, "msg.no.colon.cond");
  var ifFalse = this.assignExpr(inForInit);
  return new ConditionalExpression(exp, ifTrue, ifFalse);
};


proto.orExpr = function ( inForInit )
{
  var exp = this.andExpr(inForInit);
  while ( this.matchToken(Token.OR) ) {
      exp = new OrExpression(exp, this.andExpr(inForInit));
  }
  return exp;
};


proto.andExpr = function ( inForInit )
{
  var exp = this.bitOrExpr(inForInit);
  while ( this.matchToken(Token.AND) ) {
      exp = new AndExpression(exp, this.bitOrExpr(inForInit));
  }
  return exp;
};


proto.bitOrExpr = function ( inForInit )
{
  var exp = this.bitXorExpr(inForInit);
  while ( this.matchToken(Token.BITOR) ) {
      exp = new BitOrExpression(exp, this.bitXorExpr(inForInit));
  }
  return exp;
};


proto.bitXorExpr = function ( inForInit )
{
  var exp = this.bitAndExpr(inForInit);
  while ( this.matchToken(Token.BITXOR) ) {
      exp = new BitXorExpression(exp, this.bitAndExpr(inForInit));
  }
  return exp;
};


proto.bitAndExpr = function ( inForInit )
{
  var exp = this.eqExpr(inForInit);
  while ( this.matchToken(Token.BITAND) ) {
      exp = new BitAndExpression(exp, this.eqExpr(inForInit));
  }
  return exp;
};


proto.eqExpr = function ( inForInit )
{
  var exp = this.relExpr(inForInit);
  for (;;) {
      var constructor;
      switch ( this.peekToken() ) {
        case Token.EQ:
          constructor = EqualExpression;
          break;
        case Token.NE:
           constructor = NotEqualExpression;
          break;
        case Token.SHEQ:
          constructor = StrictEqualExpression;
          break;
        case Token.SHNE:
          constructor = StrictNotEqualExpression;
          break;
        default:
          return exp;
      }
      this.consumeToken();
      exp = new constructor(exp, this.relExpr(inForInit));
  }
};


proto.relExpr = function ( inForInit )
{
  var exp = this.shiftExpr();
  for (;;) {
      var constructor;
      switch ( this.peekToken() ) {
        case Token.IN:
          if ( inForInit ) return exp;
          constructor = InExpression;
          break;
        case Token.INSTANCEOF:
          constructor = InstanceofExpression;
          break;
        case Token.LE:
          constructor = LessEqualExpression;
          break;
        case Token.LT:
          constructor = LessThanExpression;
          break;
        case Token.GE:
          constructor = GreaterEqualExpression;
          break;
        case Token.GT:
          constructor = GreaterThanExpression;
          break;
        default:
          return exp;
      }
      this.consumeToken();
      exp = new constructor(exp, this.shiftExpr());
  }
};


proto.shiftExpr = function ( )
{
  var exp = this.addExpr();
  for (;;) {
      var constructor;
      switch ( this.peekToken() ) {
        case Token.LSH:
          constructor = LShiftExpression;
          break;
        case Token.RSH:
          constructor = RShiftExpression;
          break;
        case Token.URSH:
          constructor = URShiftExpression;
          break;
        default:
          return exp;
      }
      this.consumeToken();
      exp = new constructor(exp, this.addExpr());
  }
};


proto.addExpr = function ( )
{
  var exp = this.mulExpr();
  for (;;) {
      var constructor;
      switch ( this.peekToken() ) {
        case Token.ADD:
          constructor = AddExpression;
          break;
        case Token.SUB:
          constructor = SubExpression;
          break;
        default:
          return exp;
      }
      this.consumeToken();
      exp = new constructor(exp, this.mulExpr());
  }
};


proto.mulExpr = function ( )
{
  var exp = this.unaryExpr();
  for (;;) {
      var constructor;
      switch ( this.peekToken() ) {
        case Token.MUL:
          constructor = MulExpression;
          break;
        case Token.DIV:
          constructor = DivExpression;
          break;
        case Token.MOD:
          constructor = ModExpression;
          break;
        default:
          return exp;
      }
      this.consumeToken();
      exp = new constructor(exp, this.unaryExpr());
  }
};


proto.unaryExpr = function ( )
{
  var constructor;
  var needLvalue = null;
  switch( this.peekToken() ) {
    case Token.VOID:
      constructor = VoidExpression;
      break;
    case Token.NOT:
      constructor = NotExpression;
      break;
    case Token.BITNOT:
      constructor = BitNotExpression;
      break;
    case Token.TYPEOF:
      constructor = TypeofExpression;
      break;
    case Token.ADD:
      constructor = PosExpression;
      break;
    case Token.SUB:
      constructor = NegExpression;
      break;
    case Token.INC:
      constructor = PreIncExpression;
      needLvalue = "msg.bad.incr";
      break;
  case Token.DEC:
      constructor = PreDecExpression;
      needLvalue = "msg.bad.decr";
      break;
  case Token.DELPROP:
      constructor = DeleteExpression;
      break;
  default:
      var exp = this.memberExpr(true);
      // Don't look across a newline boundary for a postfix incop.
      switch ( this.peekTokenOrEOL() ) {
        case Token.INC:
          if ( !exp.hasLvalue() ) this.reportError("msg.bad.incr");
          this.consumeToken();
          return new PostIncExpression(exp);
        case Token.DEC:
          if ( !exp.hasLvalue() ) this.reportError("msg.bad.decr");
          this.consumeToken();
          return new PostDecExpression(exp);
        default:
          return exp;
      }
  }
  this.consumeToken();
  var exp = this.unaryExpr();
  if ( needLvalue  &&  !exp.hasLvalue() ) this.reportError(needLvalue);
  return new constructor(exp);
};


proto.argumentList = function ( )
{
  if ( this.matchToken(Token.RP) ) return [];
  var args = [];
  do {
      args.push( this.assignExpr(false) );
  } while ( this.matchToken(Token.COMMA) );
  this.mustMatchToken(Token.RP, "msg.no.paren.arg");
  return args;
};


proto.memberExpr = function ( allowCallSyntax )
{
  var base;
  if ( this.matchToken(Token.NEW) ) {
      var func = this.memberExpr(false);
      var args = this.matchToken(Token.LP)
                   ?  this.argumentList()
                   :  [];
      base = new NewExpression(func, args);
  } else {
      base = this.primaryExpr();
  }
  return this.memberExprTail(allowCallSyntax, base);
}


proto.memberExprTail = function ( allowCallSyntax, base )
{
  tailLoop: for (;;) {
      switch ( this.peekToken() ) {
        case Token.DOTDOT:
          this.reportError("msg.XML.not.available");

        case Token.DOT: {
          this.consumeToken();
          switch ( this.nextToken() ) {
            case Token.NAME:
              base = new DotAccessor(base, new Identifier(this.ts.getString()));
              break;
            case Token.MUL:
              this.reportError("msg.XML.not.available");
            case Token.XMLATTR:
              this.reportError("msg.XML.not.available");
            default:
              this.reportError("msg.no.name.after.dot");
          }
        }
        break;

        case Token.DOTQUERY:
          this.reportError("msg.XML.not.available");

        case Token.LB:
          this.consumeToken();
          base = new BracketAccessor(base, this.expr(false));
          this.mustMatchToken(Token.RB, "msg.no.bracket.index");
          break;

        case Token.LP:
          if ( !allowCallSyntax ) break tailLoop;
          this.consumeToken();
          base = new CallExpression(base, this.argumentList());
          break;

        default:
          break tailLoop;
      }
  }
  return base;
};


proto.primaryExpr = function ( )
{
  var exp;
  var ttFlagged = this.nextFlaggedToken();
  var tt = ttFlagged & CLEAR_TI_MASK;
  switch ( tt ) {

    case Token.FUNCTION:
      return this.functionExpr();

    case Token.LB: {
      var elems = [];
      elemLoop: for (;;) {
          switch ( this.peekToken() ) {
            case Token.RB:
              this.consumeToken();
              break elemLoop;
            case Token.COMMA:
              while ( this.matchToken(Token.COMMA) ) {
                  elems.push(new Elision());
              }
              break;
            default:
              elems.push(this.assignExpr(false));
              if ( this.matchToken(Token.COMMA) ) {
                  continue elemLoop;
              } else if ( this.matchToken(Token.RB) ) {
                  break elemLoop;
              } else {
                  this.reportError("msg.no.bracket.arg");
              }
          }
      }
      return new ArrayInitializer(elems);
    }

    case Token.LC: {
      var pairs = [];
      commaloop: do {
          var prop;
          switch ( this.peekToken() ) {
            case Token.NAME:
              this.consumeToken();
              prop = new Identifier(this.ts.getString());
              break;
            case Token.STRING:
              this.consumeToken();
              prop = new StringLiteral(this.ts.getString());
              break;
            case Token.NUMBER:
              this.consumeToken();
              prop = new NumberLiteral(this.ts.getString());
              break;
            case Token.RC:
              // trailing comma is OK.
              break commaloop;
          default:
              this.reportError("msg.bad.prop");
              break commaloop;
          }
          this.mustMatchToken(Token.COLON, "msg.no.colon.prop");
          pairs.push({prop:prop, exp:this.assignExpr(false)});
      } while ( this.matchToken(Token.COMMA) );
      this.mustMatchToken(Token.RC, "msg.no.brace.prop");
      return new ObjectInitializer(pairs);
    }

    case Token.LP:
      var exp = this.expr(false);
      this.mustMatchToken(Token.RP, "msg.no.paren");
      return exp;

    case Token.XMLATTR:
      this.reportError("msg.XML.not.available");

    case Token.NAME:
      var name = new Identifier(this.ts.getString());
      if ( ttFlagged & TI_CHECK_LABEL ) {
          if ( this.matchToken(Token.COLON) ) throw new LabelException(name);
      }
      return name;

    case Token.NUMBER:
      return new NumberLiteral(this.ts.getString());

    case Token.STRING:
      return new StringLiteral(this.ts.getString());

    case Token.DIV:
    case Token.ASSIGN_DIV:
      // Got / or /= which should be treated as regexp in fact
      this.ts.readRegExp(tt);
      return new RegExpLiteral(this.ts.getString());

    case Token.NULL:
      return new NullLiteral();
      
    case Token.THIS:
      return new ThisExpression();

    case Token.TRUE:
      return new TrueLiteral();

    case Token.FALSE:
      return new FalseLiteral();

    case Token.RESERVED:
      this.reportError("msg.reserved.id");
      break;

    case Token.ERROR:
      /* the scanner or one of its subroutines reported the error. */
      break;

    case Token.EOF:
      this.reportError("msg.unexpected.eof");
      break;

    default:
      this.reportError("msg.syntax");
      break;
  }
  return null;    // should never reach here
}



          return {
              Parser: Parser
          };
      }();
  }
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.Parser = Parser;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( this.Concurrent.Thread.Compiler.CfConvert === undefined ) this.Concurrent.Thread.Compiler.CfConvert = undefined;
  if ( this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError === undefined ) this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Data.Error ) {
with ( Concurrent.Thread ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';








var IL = Concurrent.Thread.Compiler.IntermediateLanguage;












var Cf = "$Concurrent_Thread_Compiler_Cf";


function CfConvert ( func ) {
  var cache = new IdentifierMap();
  var start = CfTarget(func.start, cache);
  var cache2 = new IdentifierMap();
  cache.values().forEach(function( it ){
      cache2.put(new Identifier(it.id), it);
  });
  var body  = cons(null, nil());
  append = adder(body);
  cacheToList(cache2).forEach(function( it ){
      return append(cache2.get(it));
  });
  return new IL.Function(func.name, func.params, func.vars, body.cdr, start);
}


function cacheToList ( cache ) {
  // Resolves exception-dependency and sort blocks in valid order.
  var blocks = [];
  var depends = new IdentifierMap();
  cache.values().forEach(function( it ){
      blocks.push(it);
      depends.put(
          new Identifier(it.id),
          it.exception instanceof IL.Block ? new Identifier(it.exception.id) : undefined
      );
  });
  return check_cyclic(depends);
}



var CyclicExceptionHandlerError = Error.extend(
  function ( $super, message ) { $super(message); },
  {name: NAMESPACE + ".CyclicExceptionHandlerError"}
);

function check_cyclic ( depends ) {
  var ok = {};
  function traverse ( id, path ) {
      if ( ok[id] ) return "OK";
      var next = depends.get(id);
      if ( !next ) {
          ok[id] = true;
          path.push(id);
          return "OK";
      }
      path.forEach(function( it ){
          if ( it.valueOf() == id.valueOf() ) {
              throw new CyclicExceptionHandlerError("cyclic exception handler: " + path.concat([id]).join(" -> "));
          }
      });
      path.push(id);
      traverse(next, path);
      ok[id] = true;
      return "OK";
  }
  var result = [];
  depends.keys().forEach(function( it ){
      var path = [];
      traverse(it, path);
      result = path.concat(result);
  });
  return result.reverse();
}


function CfTarget ( b, cache ) {
  if ( b === "return" || b === "throw" ) return b;
  if ( cache.get(new Identifier(b.id)) ) return cache.get(new Identifier(b.id));
  return b[Cf](cache);
}


IL.GotoBlock.prototype[Cf] = function ( cache ) {
  var block = new IL.GotoBlock();
  cache.put(new Identifier(this.id), block);
  block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
  block.body      = this.body.map(function( it ){ return it[Cf](cache); });
  block.arg       = this.arg[Cf](cache);
  block.target    = CfTarget(this.target, cache);
  block.exception = CfTarget(this.exception, cache);
  return block;
};

IL.CallBlock.prototype[Cf] = function ( cache ) {
  var block = new IL.CallBlock();
  cache.put(new Identifier(this.id), block);
  block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
  block.body      = this.body.map(function( it ){ return it[Cf](cache); });
  block.this_val  = this.this_val[Cf](cache);
  block.func      = this.func[Cf](cache);
  block.args      = this.args.map(function( it ){ return it[Cf](cache); });
  block.target    = CfTarget(this.target, cache);
  block.exception = CfTarget(this.exception, cache);
  return block;
};

IL.NewBlock.prototype[Cf] = function ( cache ) {
  var block = new IL.NewBlock();
  cache.put(new Identifier(this.id), block);
  block.scopes    = this.scopes.map(function( it ){ return it[Cf](cache); });
  block.body      = this.body.map(function( it ){ return it[Cf](cache); });
  block.func      = this.func[Cf](cache);
  block.args      = this.args.map(function( it ){ return it[Cf](cache); });
  block.target    = CfTarget(this.target, cache);
  block.exception = CfTarget(this.exception, cache);
  return block;
};


IL.ExpStatement.prototype[Cf] = function ( cache ) {
  return new IL.ExpStatement(
      this.exp[Cf](cache)
  );
};

IL.CondStatement.prototype[Cf] = function ( cache ) {
  return new IL.CondStatement(
      this.cond[Cf](cache),
      CfTarget(this.target, cache)
  );
};

IL.RecvStatement.prototype[Cf] = function ( cache ) {
  return new IL.RecvStatement(
      this.assignee[Cf](cache)
  );
};

IL.EnumStatement.prototype[Cf] = function ( cache ) {
  return new IL.EnumStatement(
      this.exp[Cf](cache),
      this.assignee[Cf](cache)
  );
};


Expression.prototype[Cf] = function ( cache ) {
  return this;
};

UnaryExpression.prototype[Cf] = function ( cache ) {
  return new this.constructor(this.exp[Cf](cache));
};

BinaryExpression.prototype[Cf] = function ( cache ) {
  return new this.constructor(this.left[Cf](cache), this.right[Cf](cache));
};

ArrayInitializer.prototype[Cf] = function ( cache ) {
  return new ArrayInitializer(this.elems.map(function( it ){
      return it[Cf](cache);
  }));
};

FunctionExpression.prototype[Cf] = function ( cache ) {
  return prepareTree(this);
};

ObjectInitializer.prototype[Cf] = function ( cache ) {
  return new ObjectInitializer(this.pairs.map(function( it ){
      return { prop: it.prop,  exp: it.exp[Cf](cache) };
  }));
};

DotAccessor.prototype[Cf] = function ( cache ) {
  return new DotAccessor(this.base[Cf](cache), this.prop);
};

ConditionalExpression.prototype[Cf] = function ( cache ) {
  return new ConditionalExpression(
      this.cond[Cf](cache),
      this.texp[Cf](cache),
      this.fexp[Cf](cache)
  );
};


          return {
              CfConvert: CfConvert, CyclicExceptionHandlerError: CyclicExceptionHandlerError
          };
      }();
  }
}
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CfConvert = CfConvert;
  this.Concurrent.Thread.Compiler.CyclicExceptionHandlerError = CyclicExceptionHandlerError;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Functional || (typeof this.Data.Functional != 'object' && typeof this.Data.Functional != 'function') ) this.Data.Functional = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.CsConvert === undefined ) this.Concurrent.Thread.Compiler.CsConvert = undefined;
with ( function(){
with ( Data.Functional ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Compiler';








var IL = Concurrent.Thread.Compiler.IntermediateLanguage;








var Cs = "Concurrent.Thread.Compiler.CsConvert";
var STACK_VAR = "$Concurrent_Thread_stack";

var undefinedExp = new VoidExpression(new NumberLiteral(0));
var emptyLabel   = new Identifier("");

function isStackVar ( v ) {
  return v instanceof Identifier
      && v.valueOf().match(/^$Concurrent_Thread_stack/);
}


function Context ( ) {
  this.stackVars = [];
  this.contBreak    = new IdentifierMap();
  this.contContinue = new IdentifierMap();
  this.contReturn   = "return";
  this.contThrow    = "throw";
  this.scopes       = [];
}

var proto = Context.prototype;

proto.getStackVar = function ( n ) {
  n = Math.floor(n);
  if ( isNaN(n) || n < 0 ) Kit.codeBug("must be integer greater than zero");
  for ( var i=this.stackVars.length;  i <= n;  i++ ) {
      this.stackVars[i] = new Identifier(STACK_VAR + i);
  }
  return this.stackVars[n];
};

proto.putBreakLabels = function ( labels, target ) {
  if ( !labels.length ) return this.contBreak;
  var restore = this.contBreak;
  this.contBreak = this.contBreak.clone();
  for ( var i=0;  i < labels.length;  i++ ) {
      this.contBreak.put(labels[i], target);
  }
  return restore;
};

proto.putBreakAndContinueLabels = function ( labels, breakTarget, continueTarget ) {
  if ( !labels.length ) {
      return {
          contBreak   : this.contBreak,
          contContinue: this.contContinue
      };
  }
  var restore = {
      contBreak   : this.contBreak,
      contContinue: this.contContinue
  };
  this.contBreak    = this.contBreak.clone();
  this.contContinue = this.contContinue.clone();
  for ( var i=0;  i < labels.length;  i++ ) {
      this.contBreak.put(labels[i], breakTarget);
      this.contContinue.put(labels[i], continueTarget);
  }
  return restore;
};

proto.getScopes = function ( ) {
  return this.scopes.slice(0, this.scopes.length);
};

proto.pushScope = function ( /* variable args */ ) {
  return this.scopes.push.apply(this.scopes, arguments);
};

proto.popScope = function ( ) {
  return this.scopes.pop();
};

proto.makeGotoBlock = function ( arg, target ) {
  return new IL.GotoBlock(this.getScopes(), nil(), arg, target, this.contThrow);
};




function CsConvert ( func ) {
  var context = new Context();
  var last_block = new IL.GotoBlock([], nil(), undefinedExp, "return", "throw");
  func.body  = CsStatements(func.body, list(last_block), context, 0);
  func.start = func.body.car;
  func.vars  = func.vars.concat(context.stackVars);
  return func;
}


function CsStatements ( stmts, follows, ctxt, sttop ) {
  if ( stmts.isNil() ) return follows;
  follows = CsStatements(stmts.cdr, follows, ctxt, sttop);
  return stmts.car[Cs](follows, ctxt, sttop);
}

function CsReference ( exp, ctxt, sttop, rest ) {  // Expression -> Context -> Int -> (Expression -> <Block>) -> <Block>
  if ( exp instanceof DotAccessor ) {
      var e = new DotAccessor(ctxt.getStackVar(sttop), exp.prop);
      var follows = rest(e, sttop+1);
      return exp.base[Cs](follows, ctxt, sttop);
  } else if ( exp instanceof BracketAccessor ) {
      var e = new BracketAccessor(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1));
      var follows = rest(e, sttop+2);
      follows = exp.right[Cs](follows, ctxt, sttop+1);
      return exp.left[Cs](follows, ctxt, sttop);
  } else if ( exp instanceof Identifier ) {
      return rest(exp, sttop);
  } else {
      var follows = rest(ctxt.getStackVar(sttop), sttop+1);
      return exp[Cs](follows, ctxt, sttop);
  }
}



EmptyStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  return follows;
};

Block.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var restore = ctxt.putBreakLabels(this.labels, follows.car);
  follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows);
  try {
      return CsStatements(this.body, follows, ctxt, sttop);
  } finally {
      ctxt.contBreak = restore;
  }
};

ExpStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  return this.exp[Cs](follows, ctxt, sttop);
};


IfStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
  var restore = ctxt.putBreakLabels(this.labels, next_block);
  try {
      follows = this.body[Cs](follows, ctxt, sttop);
      follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
      return this.cond[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak = restore;
  }
};

IfElseStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
  var restore = ctxt.putBreakLabels(this.labels, next_block);
  try {
      follows = this.tbody[Cs](follows, ctxt, sttop);
      var true_block = follows.car;
      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows);
      follows = this.fbody[Cs](follows, ctxt, sttop);
      follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), true_block) );
      return this.cond[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak = restore;
  }
};


DoWhileStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block  = follows.car;
  var first_block = ctxt.makeGotoBlock(undefinedExp, null);
  follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
  if ( this.cond.containsFunctionCall() ) {
      follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), first_block) );
      follows = this.cond[Cs](follows, ctxt, sttop);
  } else {
      follows.car.prependStatement( new IL.CondStatement(this.cond, first_block) );
  }
  var continue_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
  var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, continue_block);
  try {
      follows = this.body[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak    = restore.contBreak;
      ctxt.contContinue = restore.contContinue;
  }
  first_block.target = follows.car;
  return cons( ctxt.makeGotoBlock(undefinedExp, first_block),
               cons(first_block, follows) );
};

WhileStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block  = follows.car;
  var first_block = ctxt.makeGotoBlock(undefinedExp, null);
  follows = cons( ctxt.makeGotoBlock(undefinedExp, first_block), follows );
  var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, first_block);
  try {
      follows = this.body[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak    = restore.contBreak;
      ctxt.contContinue = restore.contContinue;
  }
  if ( this.cond.containsFunctionCall() ) {
      follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
      follows = this.cond[Cs](follows, ctxt, sttop);
  } else {
      follows.car.prependStatement( new IL.CondStatement(new NotExpression(this.cond), next_block) );
  }
  first_block.target = follows.car;
  return cons( ctxt.makeGotoBlock(undefinedExp, first_block),
               cons(first_block, follows) );
};

ForStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  var last_block = ctxt.makeGotoBlock(undefinedExp, null);
  follows = cons(last_block, follows);
  if ( this.incr ) follows = this.incr[Cs](follows, ctxt, sttop);
  var incr_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
  var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, incr_block);
  try {
      follows = this.body[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak    = restore.contBreak;
      ctxt.contContinue = restore.contContinue;
  }
  if ( this.cond ) {
      if ( this.cond.containsFunctionCall() ) {
          follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
          follows = this.cond[Cs](follows, ctxt, sttop);
      } else {
          follows.car.prependStatement( new IL.CondStatement(new NotExpression(this.cond), next_block) );
      }
  }
  last_block.target = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
  if ( this.init ) {
      follows = this.init[Cs](follows, ctxt, sttop);
  }
  return follows;
};

ForInStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( !this.lhs.hasLvalue() ) Kit.codeBug('for-in requires lvalue on the left hand side of "in": ' + this);
  var next_block = follows.car;
  var loop_block = ctxt.makeGotoBlock(undefinedExp, null);
  follows = cons( ctxt.makeGotoBlock(undefinedExp, loop_block), follows );
  var restore = ctxt.putBreakAndContinueLabels(this.labels.concat(emptyLabel), next_block, loop_block);
  try {
      follows = this.body[Cs](follows, ctxt, sttop+2);
  } finally {
      ctxt.contBreak    = restore.contBreak;
      ctxt.contContinue = restore.contContinue;
  }
  if ( this.lhs.containsFunctionCall() ) {
      follows = CsReference(this.lhs, ctxt, sttop+2, function( exp ){
          follows.car.prependStatement( make_assign(
              exp,
              new BracketAccessor(
                  ctxt.getStackVar(sttop),
                  new PostIncExpression(ctxt.getStackVar(sttop+1))
              )
          ) );
          return follows;
      });
  } else {
      follows.car.prependStatement( make_assign(
          this.lhs,
          new BracketAccessor(
              ctxt.getStackVar(sttop),
              new PostIncExpression(ctxt.getStackVar(sttop+1))
          )
      ) );
  }
  follows.car.prependStatement( new IL.CondStatement(
      new GreaterEqualExpression(
          ctxt.getStackVar(sttop+1),
          new DotAccessor(ctxt.getStackVar(sttop), new Identifier("length"))
      ),
      next_block
  ) );
  loop_block.target = follows.car;
  follows = cons( loop_block, follows );
  follows = cons( ctxt.makeGotoBlock(undefinedExp, loop_block), follows );
  follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop+1), new NumberLiteral(0)) );
  if ( this.exp.containsFunctionCall() ) {
      follows.car.prependStatement( new IL.EnumStatement(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop)) );
      follows = this.exp[Cs](follows, ctxt, sttop);
  } else {
      follows.car.prependStatement( new IL.EnumStatement(this.exp, ctxt.getStackVar(sttop)) );
  }
  return follows;
};


ContinueStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  return cons(
      ctxt.makeGotoBlock(
          undefinedExp,
          ctxt.contContinue.get( this.target ? this.target : emptyLabel )
      ),
      follows
  );
};

BreakStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var restore = ctxt.putBreakLabels(this.labels, follows.car);
  try {
      return cons(
          ctxt.makeGotoBlock(
              undefinedExp,
              ctxt.contBreak.get( this.target ? this.target : emptyLabel )
          ),
          follows
      );
  } finally {
      ctxt.contBreak = restore;
  }
};

ReturnStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.exp ) {
      if ( this.exp.containsFunctionCall() ) {
          follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contReturn), follows );
          return this.exp[Cs](follows, ctxt, sttop);
      } else {
          return cons( ctxt.makeGotoBlock(this.exp, ctxt.contReturn), follows );
      }
  } else {
      return cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contReturn), follows );
  }
};


WithStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  var restore = ctxt.putBreakLabels(this.labels, next_block);
  try {
      ctxt.pushScope(ctxt.getStackVar(sttop));
      try {
          follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
          follows = this.body[Cs](follows, ctxt, sttop+1);
      } finally {
          ctxt.popScope();
      }
      follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
      return this.exp[Cs](follows, ctxt, sttop);
  } finally {
      ctxt.contBreak = restore;
  }
};


SwitchStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  var restore = ctxt.putBreakLabels(this.labels.concat(emptyLabel) , next_block);
  try {
      var default_target  = next_block;
      var cond_and_target = this.clauses.reverse().map(function( clause ){
          follows = cons( ctxt.makeGotoBlock(undefinedExp, follows.car), follows );
          follows = CsStatements(clause.body, follows, ctxt, sttop);
          var clause_block = follows.car;
          if ( clause instanceof DefaultClause ) {
              default_target = clause_block;
              ignore();
          } else {
              return {cond:clause.exp, target:clause_block};
          }
      });
      follows = cons( ctxt.makeGotoBlock(undefinedExp, default_target), follows );
      cond_and_target.forEach(function( it ){
          if ( it.cond.containsFunctionCall() ) {
              follows.car.prependStatement(
                  new IL.CondStatement(
                      new StrictEqualExpression(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1)),
                      it.target
                  )
              );
              follows = it.cond[Cs](follows, ctxt, sttop+1);
          } else {
              follows.car.prependStatement(
                  new IL.CondStatement(
                      new StrictEqualExpression(ctxt.getStackVar(sttop), it.cond),
                      it.target
                  )
              );
          }
      });
      return this.exp[Cs](follows, ctxt,sttop);
  } finally {
      ctxt.contBreak = restore;
  }
};


ThrowStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.exp.containsFunctionCall() ) {
      follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contThrow), follows );
      return this.exp[Cs](follows, ctxt, sttop);
  } else {
      return cons( ctxt.makeGotoBlock(this.exp, ctxt.contThrow), follows );
  }
};

TryCatchStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
  var restore = ctxt.putBreakLabels(this.labels, next_block);
  try {
      follows = this.catchBlock[Cs](follows, ctxt, sttop);
      follows.car.prependStatement( new IL.RecvStatement(this.variable) );
      var storeContThrow = ctxt.contThrow;
      ctxt.contThrow = follows.car;
      try {
          follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
          return this.tryBlock[Cs](follows, ctxt, sttop);
      } finally {
          ctxt.contThrow = storeContThrow;
      }
  } finally {
      ctxt.contBreak = restore;
  }
};

TryFinallyStatement.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var next_block = follows.car;
  follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
  var restoreBreak = ctxt.putBreakLabels(this.labels, next_block);
  try {
      var self = this;

      var contBreak = new IdentifierMap();
      ctxt.contBreak.keys().forEach(function( label ){
          follows = cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contBreak.get(label)), follows );
          follows = self.finallyBlock[Cs](follows, ctxt, sttop);
          contBreak.put(label, follows.car);
      });
      
      var contContinue = new IdentifierMap();
      ctxt.contContinue.keys().forEach(function( label ){
          follows = cons( ctxt.makeGotoBlock(undefinedExp, ctxt.contContinue.get(label)), follows );
          follows = self.finallyBlock[Cs](follows, ctxt, sttop);
          contContinue.put(label, follows.car);
      });
      
      follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contReturn), follows );
      follows = this.finallyBlock[Cs](follows, ctxt, sttop+1);
      follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
      var contReturn = follows.car;
      
      follows = cons( ctxt.makeGotoBlock(ctxt.getStackVar(sttop), ctxt.contThrow), follows );
      follows = this.finallyBlock[Cs](follows, ctxt, sttop+1);
      follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
      var contThrow = follows.car;

      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
      follows = this.finallyBlock[Cs](follows, ctxt, sttop);
      
      var restoreContinue = ctxt.contContinue;
      var restoreReturn   = ctxt.contReturn;
      var restoreThrow    = ctxt.contThrow;
      ctxt.contBreak    = contBreak;
      ctxt.contContinue = contContinue;
      ctxt.contReturn   = contReturn;
      ctxt.contThrow    = contThrow;
      try {
          return this.tryBlock[Cs](follows, ctxt, sttop);
      } finally {
          ctxt.contContinue = restoreContinue;
          ctxt.contReturn   = restoreReturn;
          ctxt.contThrow    = restoreThrow;
      }
  } finally {
      ctxt.contBreak = restoreBreak;
  }
};



function make_assign ( left, right ) {
  return new IL.ExpStatement( new SimpleAssignExpression(left, right) );
}

Expression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), this) );
  return follows;
};

ArrayInitializer.prototype[Cs] = function ( follows, ctxt, sttop ) {
  for ( var asis_from=this.elems.length-1;  asis_from >= 0;  asis_from-- ) {
      if ( this.elems[asis_from].containsFunctionCall() ) break;
  }
  asis_from++;
  var elems = [];
  for ( var i=0;  i < asis_from;  i++ ) {
      elems[i] = ctxt.getStackVar(sttop+i);
  }
  for ( ;  i < this.elems.length;  i++ ) {
      elems[i] = this.elems[i];
  }
  follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ArrayInitializer(elems)) );
  for ( var i=asis_from-1;  i >= 0;  i-- ) {
      follows = this.elems[i][Cs](follows, ctxt, sttop+i);
  }
  return follows;
};

ObjectInitializer.prototype[Cs] = function ( follows, ctxt, sttop ) {
  for ( var asis_from=this.pairs.length-1;  asis_from >= 0;  asis_from-- ) {
      if ( this.pairs[asis_from].exp.containsFunctionCall() ) break;
  }
  asis_from++;
  var pairs = [];
  for ( var i=0;  i < asis_from;  i++ ) {
      pairs[i] = {prop:this.pairs[i].prop, exp:ctxt.getStackVar(sttop+i)};
  }
  for ( ;  i < this.pairs.length;  i++ ) {
      pairs[i] = this.pairs[i];
  }
  follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ObjectInitializer(pairs)) );
  for ( var i=asis_from-1;  i >= 0;  i-- ) {
      follows = this.pairs[i].exp[Cs](follows, ctxt, sttop+i);
  }
  return follows;
};

UnaryExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.exp.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new this.constructor(ctxt.getStackVar(sttop))) );
      return this.exp[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

BinaryExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.right.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(
          ctxt.getStackVar(sttop),
          new this.constructor(ctxt.getStackVar(sttop), ctxt.getStackVar(sttop+1))
      ) );
      follows = this.right[Cs](follows, ctxt, sttop+1);
      return this.left[Cs](follows, ctxt, sttop);
  } else if ( this.left.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(
          ctxt.getStackVar(sttop),
          new this.constructor(ctxt.getStackVar(sttop), this.right)
      ) );
      return this.left[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

DotAccessor.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.base.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(
          ctxt.getStackVar(sttop),
          new DotAccessor(ctxt.getStackVar(sttop), this.prop)
      ) );
      return this.base[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

CallExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var self = this;
  return CsReference(this.func, ctxt, sttop, function ( func, sttop2 ) {
      for ( var asis_from=self.args.length-1;  asis_from >= 0;  asis_from-- ) {
          if ( self.args[asis_from].containsFunctionCall() ) break;
      }
      asis_from++;
      var args = [];
      for ( var i=0;  i < asis_from;  i++ ) {
          args[i] = ctxt.getStackVar(sttop2+i);
      }
      for ( ;  i < self.args.length;  i++ ) {
          args[i] = self.args[i];
      }
      follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
      follows = cons( new IL.CallBlock(
                          ctxt.getScopes(),
                          nil(),
                          func instanceof DotAccessor     ? func.base :
                          func instanceof BracketAccessor ? func.left : new NullLiteral(),
                          func,
                          args,
                          follows.car,
                          ctxt.contThrow
                      ), follows );
      for ( var i=asis_from-1;  i >= 0;  i-- ) {
          follows = self.args[i][Cs](follows, ctxt, sttop2+i);
      }
      return follows;
  });
};

NewExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  for ( var asis_from=this.args.length-1;  asis_from >= 0;  asis_from-- ) {
      if ( this.args[asis_from].containsFunctionCall() ) break;
  }
  asis_from++;
  var args = [];
  for ( var i=0;  i < asis_from;  i++ ) {
      args[i] = ctxt.getStackVar(sttop+1+i);
  }
  for ( ;  i < this.args.length;  i++ ) {
      args[i] = this.args[i];
  }
  follows.car.prependStatement( new IL.RecvStatement(ctxt.getStackVar(sttop)) );
  follows = cons( new IL.NewBlock(
                      ctxt.getScopes(),
                      nil(),
                      ctxt.getStackVar(sttop),
                      args,
                      follows.car,
                      ctxt.contThrow
                  ), follows );
  for ( var i=asis_from-1;  i >= 0;  i-- ) {
      follows = this.args[i][Cs](follows, ctxt, sttop+1+i);
  }
  this.func[Cs](follows, ctxt, sttop);
  return follows;
};

AssignExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  var self = this;
  if ( this.right.containsFunctionCall() ) {
      return CsReference(this.left, ctxt, sttop, function ( left, sttop2 ) {
          follows.car.prependStatement( make_assign(
              ctxt.getStackVar(sttop),
              new self.constructor(left, ctxt.getStackVar(sttop2))
          ) );
          return self.right[Cs](follows, ctxt, sttop2);
      });
  } else if ( this.left.containsFunctionCall() ) {
      return CsReference(this.left, ctxt, sttop, function ( left, sttop2 ) {
          follows.car.prependStatement( make_assign(
              ctxt.getStackVar(sttop),
              new self.constructor(left, self.right)
          ) );
          return follows;
      });
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

AndExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.right.containsFunctionCall() ) {
      var next_block = follows.car;
      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
      follows = this.right[Cs](follows, ctxt, sttop);
      follows.car.prependStatement( new IL.CondStatement(new NotExpression(ctxt.getStackVar(sttop)), next_block) );
      return this.left[Cs](follows, ctxt, sttop);
  } else if ( this.left.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new AndExpression(ctxt.getStackVar(sttop), this.right)) );
      return this.left[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

OrExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.right.containsFunctionCall() ) {
      var next_block = follows.car;
      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
      follows = this.right[Cs](follows, ctxt, sttop);
      follows.car.prependStatement( new IL.CondStatement(ctxt.getStackVar(sttop), next_block) );
      return this.left[Cs](follows, ctxt, sttop);
  } else if ( this.left.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new OrExpression(ctxt.getStackVar(sttop), this.right)) );
      return this.left[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

ConditionalExpression.prototype[Cs] = function ( follows, ctxt, sttop ) {
  if ( this.texp.containsFunctionCall() || this.fexp.containsFunctionCall() ) {
      var next_block = follows.car;
      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
      follows = this.texp[Cs](follows, ctxt, sttop);
      var true_block = follows.car;
      follows = cons( ctxt.makeGotoBlock(undefinedExp, next_block), follows );
      follows = this.fexp[Cs](follows, ctxt, sttop);
      follows.car.prependStatement(new IL.CondStatement(ctxt.getStackVar(sttop), true_block));
      return this.cond[Cs](follows, ctxt, sttop);
  } else if ( this.cond.containsFunctionCall() ) {
      follows.car.prependStatement( make_assign(ctxt.getStackVar(sttop), new ConditionalExpression(ctxt.getStackVar(sttop), this.texp, this.fexp)) );
      return this.cond[Cs](follows, ctxt, sttop);
  } else {
      return Expression.prototype[Cs].apply(this, arguments);
  }
};

          return {
              CsConvert: CsConvert
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CsConvert = CsConvert;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.CvConvert === undefined ) this.Concurrent.Thread.Compiler.CvConvert = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread.Compiler';












var IL = IntermediateLanguage;


var Cv = "$Concurrent_Thread_Compiler_CvConvert";



function CvConvert ( func ) {
  var vars  = new IdentifierSet()
  function add_vars ( /* variable arguments */ ) {
      return vars.add.apply(vars, arguments);
  }
  var decls     = cons(null, nil());
  var add_decls = adder(decls);
  for ( var c=func.body;  !c.isNil();  c=c.cdr ) {
      c.car = c.car[Cv](add_vars, add_decls);
  }
  return new IL.Function(func.name, func.params, vars.toArray(), concat(decls, func.body).cdr);
}



Statement.prototype[Cv] = function ( add_vars, add_decls ) {
  return this;
};


Block.prototype[Cv] = function ( add_vars, add_decls ) {
  for ( var c=this.body;  !c.isNil();  c=c.cdr ) {
      c.car = c.car[Cv](add_vars, add_decls);
  }
  return this;
};


VarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  var assigns = [];
  for ( var i=0;  i < this.decls.length;  i++ ) {
      add_vars(this.decls[i].id);
      if ( this.decls[i].exp ) {
          assigns.push( new SimpleAssignExpression(this.decls[i].id, this.decls[i].exp) );
      }
  }
  if ( !assigns.length ) {
      return new EmptyStatement([], this.lineno, this.source);
  } else {
      var exp = assigns[0];
      for ( var i=1;  i < assigns.length;  i++ ) {
          exp = new CommaExpression(exp, assigns[i]);
      }
      return new ExpStatement([], exp, this.lineno, this.source);
  }
};


IfStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  this.body = this.body[Cv](add_vars, add_decls);
  return this;
};


IfElseStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  this.tbody = this.tbody[Cv](add_vars, add_decls);
  this.fbody = this.fbody[Cv](add_vars, add_decls);
  return this;
};


DoWhileStatement.prototype[Cv] = IfStatement.prototype[Cv];


WhileStatement.prototype[Cv] = IfStatement.prototype[Cv];


ForStatement.prototype[Cv] = IfStatement.prototype[Cv];


ForVarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  var init = (new VarStatement([], this.decls))[Cv](add_vars, add_decls);
  if ( init instanceof EmptyStatement ) {
      init = null;
  } else {
      init = init.exp;
  }
  return new ForStatement(this.labels, init, this.cond, this.incr, this.body[Cv](add_vars, add_decls), this.lineno, this.source);
};


ForInStatement.prototype[Cv] = IfStatement.prototype[Cv];


ForInVarStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  add_vars(this.decl.id);
  var for_in = new ForInStatement(this.labels, this.decl.id, this.exp, this.body[Cv](add_vars, add_decls), this.lineno, this.source);
  if ( this.decl.exp ) {
      return new Block([], list(
          new ExpStatement([], new SimpleAssignExpression(this.decl.id, this.decl.exp), this.lineno, this.source),
          for_in
      ), this.lineno, this.source);
  } else {
      return for_in;
  }
};


ForEachStatement.prototype[Cv] = IfStatement.prototype[Cv];


ForEachVarStatement.prototype[Cv] = ForInVarStatement.prototype[Cv];


WithStatement.prototype[Cv] = IfStatement.prototype[Cv];


SwitchStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  for ( var c=this.clauses;  !c.isNil();  c=c.cdr ) {
      c.car = c.car[Cv](add_vars, add_decls);
  }
  return this;
};


CaseClause.prototype[Cv] = Block.prototype[Cv];


DefaultClause.prototype[Cv] = Block.prototype[Cv];


TryCatchStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  add_vars(this.variable);
  this.tryBlock   = this.tryBlock[Cv](add_vars, add_decls);
  this.catchBlock = this.catchBlock[Cv](add_vars, add_decls);
  return this;
};


TryFinallyStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  this.tryBlock     = this.tryBlock[Cv](add_vars, add_decls);
  this.finallyBlock = this.finallyBlock[Cv](add_vars, add_decls);
  return this;
};


TryCatchFinallyStatement.prototype[Cv] = function ( add_vars, add_decls ) {
  add_vars(this.variable);
  this.tryBlock     = this.tryBlock[Cv](add_vars, add_decls);
  this.catchBlock   = this.catchBlock[Cv](add_vars, add_decls);
  this.finallyBlock = this.finallyBlock[Cv](add_vars, add_decls);
  return this;
};


FunctionDeclaration.prototype[Cv] = function ( add_vars, add_decls ) {
  add_vars(this.name);
  add_decls( new ExpStatement(
      [],
      new SimpleAssignExpression(
          this.name,
          new FunctionExpression(null, this.params, this.body)
      ),
      this.lineno,
      this.source
  ));
  return new EmptyStatement([]);
};


          return {
              CvConvert: CvConvert
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CvConvert = CvConvert;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Data.Cons.Util || (typeof this.Data.Cons.Util != 'object' && typeof this.Data.Cons.Util != 'function') ) this.Data.Cons.Util = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( this.Concurrent.Thread.Compiler.CzConvert === undefined ) this.Concurrent.Thread.Compiler.CzConvert = undefined;
with ( function(){
with ( Data.Cons.Util ) {
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */


NAMESPACE = 'Concurrent.Thread.Compiler';






var IL = Concurrent.Thread.Compiler.IntermediateLanguage;









var Cz = "$Concurrent_Thread_Compiler_CzConvert";

var PREFIX   = "$Concurrent_Thread_";
var var_this = new Identifier(PREFIX+"this");
var var_args = new Identifier(PREFIX+"arguments");
var var_cont = new Identifier(PREFIX+"continuation");
var var_self = new Identifier(PREFIX+"self");
var var_compiled     = new Identifier(PREFIX+"compiled");
var var_intermediate = new Identifier(PREFIX+"intermediate");

var name_arguments = new Identifier("arguments");
var name_prototype = new Identifier("prototype");
var name_apply     = new Identifier("apply");
var name_procedure = new Identifier("procedure");
var name_this_val  = new Identifier("this_val");
var name_exception = new Identifier("exception");

var var_null_function = new Identifier(PREFIX+"null_function");
var null_function = new FunctionDeclaration([], var_null_function, [], nil());




function CzConvert ( func ) {
  var body = inner_function(func);
  return new FunctionExpression(
             null,
             [var_this, var_args, var_cont],
             list(
                 new ReturnStatement([],
                     new CallExpression(
                         new DotAccessor(body, name_apply),
                         [var_this, var_args]
                     )
                 )
             )
         );
}




var arguments_callee = new DotAccessor(name_arguments, new Identifier("callee"));

function inner_function ( func ) {
  var blocks = func.body.map(function(it){ return it[Cz](); });
  blocks = cons( var_declaration(func.vars),
           cons( null_function,
           cons( make_assign(var_args, name_arguments),
           cons( make_assign(arguments_callee, var_self),
                 blocks ) ) ) );
  adder(blocks)( make_return(func.start) );
  return new FunctionExpression(null, func.params, blocks);
}

function var_declaration ( vars ) {
  if ( !vars.length ) return new EmptyStatement([]);
  var decls = [];
  vars.forEach(function( it ){
      decls.push({ id:it, exp:null });
  });
  return new VarStatement([], decls);
}


function make_assign ( lhs, rhs ) {
  return new ExpStatement( [], new SimpleAssignExpression(lhs, rhs) );
}


var var_cont_ex = new DotAccessor(var_cont, name_exception);

function target_to_name ( b ) {
  if ( b instanceof IL.Block ) {
      return new Identifier(PREFIX + b.id);
  } else if ( b === "return" ) {
      return var_cont;
  } else if ( b === "throw" ) {
      return var_cont_ex;
  } else {
      Kit.codeBug("invalid target");
  }
}


var undefinedExp = new VoidExpression(new Literal(0));
var name_continuation = new Identifier("continuation");
var name_timeout      = new Identifier("timeout");
var name_ret_val      = new Identifier("ret_val");

function make_return ( continuation, ret_val ) {
  return new ReturnStatement([], new ObjectInitializer([
             { prop: name_continuation, exp: target_to_name(continuation) },
             { prop: name_ret_val     , exp: ret_val || undefinedExp },
             { prop: name_timeout     , exp: undefinedExp            }
         ]) );
}


var assign_arguments = make_assign(name_arguments, var_args);

function make_continuation ( block, body ) {
  body = new Block([], body);
  for ( var i=block.scopes.length-1;  i >= 0;  i-- ) {
      body = new WithStatement([], block.scopes[i], body);
  }
  return new VarStatement([], [{
      id : target_to_name(block),
      exp: new ObjectInitializer([
               {prop: name_procedure, exp: new FunctionExpression(null, [var_intermediate], list(assign_arguments, body))},
               {prop: name_this_val , exp: new ThisExpression() },
               {prop: name_exception, exp: target_to_name(block.exception) }
           ])
  }]);
}



IL.GotoBlock.prototype[Cz] = function ( ) {
  var body = this.body.map(function( it ) {
      return it[Cz]();
  });
  body = cons(null, body);
  adder(body)( make_return(this.target, this.arg) );
  return make_continuation(this, body.cdr);
};


var string_object   = new StringLiteral('"object"');
var string_function = new StringLiteral('"function"');

IL.CallBlock.prototype[Cz] = function ( ) {
  var body = this.body.map(function( it ) {
      return it[Cz]();
  });
  body = cons(null, body);
  adder(body)( new IfElseStatement([],
      new AndExpression(
          this.func,
          new StrictEqualExpression(
              new TypeofExpression(
                  new DotAccessor(this.func, var_compiled)
              ),
              string_function
          )
      ),
      new ReturnStatement([],
          new CallExpression(
              new DotAccessor(this.func, var_compiled),
              [
                  this.this_val,
                  new ArrayInitializer(this.args),
                  target_to_name(this.target)
              ]
          )
      ),
      make_return(
          this.target,
          new CallExpression(this.func, this.args)
      )
  ) );
  return make_continuation(this, body.cdr);
};


IL.NewBlock.prototype[Cz] = function ( ) {
  var body = this.body.map(function( it ) {
      return it[Cz]();
  });
  body = cons(null, body);
  /*  // Construct the following code-tree.
      if ( CONSTRUCTOR && typeof CONSTRUCTOR.$Concurrent_Thread_compiled == "function" ) {
      $Concurrent_Thread_null_function.prototype = CONSTRUCTOR.prototype;
      $Concurrent_Thread_this = new $Concurrent_Thread_null_function();
      return CONSTRUCTOR.$Concurrent_Thread_compiled(
                 $Concurrent_Thread_this,
                 [ARG1, ARG2, ...],
                 { procedure: function($Concurrent_Thread_intermediate){
                  if ( !($Concurrent_Thread_intermediate && (typeof $Concurrent_Thread_intermediate === "object" || typeof $Concurrent_Thread_intermediate === "function") )
                    $Concurrent_Thread_intermediate = $Concurrent_Thread_this;
                  $Concurrent_Thread_this = null;  // encourages GC
                     return { continuation: CONTINUATION,
                              ret_val     : $Concurrent_Thread_intermediate,
                              timeout     : void 0                          };
                 }, this_val: this, exception: EXCEPTION }
             );
      } else {
          return { continuation: CONTINUATION,
                   ret_val     : new CONSTRUCTOR(ARG1, ARG2...),
                   timeout     : void 0
                 };
      } 
   */
  adder(body)( new IfElseStatement([],
      new AndExpression(
          this.func,
          new StrictEqualExpression(
              new TypeofExpression(
                  new DotAccessor(this.func, var_compiled)
              ),
              string_function
          )
      ),
      new Block([],
          list( 
              make_assign( new DotAccessor(var_null_function, name_prototype),
                           new DotAccessor(this.func        , name_prototype) ),
              make_assign( var_this, new NewExpression(var_null_function, []) ),
              new ReturnStatement([],
                  new CallExpression(
                      new DotAccessor(this.func, var_compiled),
                      [
                          var_this,
                          new ArrayInitializer(this.args),
                          new ObjectInitializer([
                              {prop: name_procedure, exp: new FunctionExpression(null, [var_intermediate], list(
                                  new IfStatement([],
                                      new NotExpression(
                                          new AndExpression(
                                              var_intermediate,
                                              new OrExpression(
                                                  new StrictEqualExpression(new TypeofExpression(var_intermediate), string_object),
                                                  new StrictEqualExpression(new TypeofExpression(var_intermediate), string_function)
                                              )
                                          )
                                      ),
                                      make_assign(var_intermediate, var_this)
                                  ),
                                  make_assign(var_this, new NullLiteral()),
                                  make_return(this.target, var_intermediate)
                              ))},
                              {prop: name_this_val , exp: new ThisExpression()},
                              {prop: name_exception, exp: target_to_name(this.exception)}
                           ])
                      ]
                  )
              )
          )
      ),
      make_return(this.target, new NewExpression(this.func, this.args))
  ) );
  return make_continuation(this, body.cdr);
};


IL.ExpStatement.prototype[Cz] = function ( ) {
  return new ExpStatement([], this.exp);
};


IL.CondStatement.prototype[Cz] = function ( ) {
  return new IfStatement([], this.cond, make_return(this.target));
};


IL.RecvStatement.prototype[Cz] = function ( ) {
  return make_assign(this.assignee, var_intermediate);
};


var name_push = new Identifier("push");

IL.EnumStatement.prototype[Cz] = function ( ) {
  return new Block([], list(
      make_assign(var_this, new ArrayInitializer([])),
      new ForInStatement([], var_intermediate, this.exp, 
          new ExpStatement([], 
              new CallExpression(
                  new DotAccessor(var_this, name_push),
                  [var_intermediate]
              )
          )
      ),
      make_assign(this.assignee, var_this),
      make_assign(var_this, new NullLiteral())
  ));
};

          return {
              CzConvert: CzConvert
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.Compiler.CzConvert = CzConvert;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Cons || (typeof this.Data.Cons != 'object' && typeof this.Data.Cons != 'function') ) this.Data.Cons = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( this.Concurrent.Thread.compile === undefined ) this.Concurrent.Thread.compile = undefined;
  if ( this.Concurrent.Thread.CACHE_LIMIT === undefined ) this.Concurrent.Thread.CACHE_LIMIT = undefined;
  if ( this.Concurrent.Thread.prepare === undefined ) this.Concurrent.Thread.prepare = undefined;
  if ( this.Concurrent.Thread.prepareTree === undefined ) this.Concurrent.Thread.prepareTree = undefined;
with ( function(){
with ( Data.Cons ) {
with ( Concurrent.Thread.Compiler ) {
with ( Concurrent.Thread ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread code.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread';














var IL = Concurrent.Thread.Compiler.IntermediateLanguage;






var PREFIX            = "$Concurrent_Thread_";
var var_self     = new Identifier(PREFIX + "self");
var var_compiled = new Identifier(PREFIX + "compiled");



function compile ( f ) {
  return eval(prepare(f));
}



CACHE_LIMIT = 50;
var prepare_cache = {};
var cache_history = [];


function prepare ( f ) {
  if ( typeof f != "function" ) throw new TypeError("argument must be a function");
  f = f.toString();
  var c = prepare_cache[f];
  if ( c ) return c;
  c = prepareTree(parseFunction(f)).toString();
  while ( cache_history.length >= CACHE_LIMIT  &&  cache_history.length > 0 ) {  // avoid endless loop
      delete prepare_cache[cache_history.shift()];
  }
  if ( CACHE_LIMIT >= 1 ) {
      prepare_cache[f] = c;
      cache_history.push(f);
  }
  return c;
}

function parseFunction ( f ) {
  var stmts = (new Parser()).parse("(" + f + ");");
  if ( !(stmts.car instanceof ExpStatement) ) throw new Error("not exp-statement!");
  if ( !(stmts.car.exp instanceof FunctionExpression) ) throw new Error("not function-expression!");
  return stmts.car.exp;
}



function prepareTree ( f ) {
  if ( !(f instanceof FunctionExpression) ) Kit.codeBug("not FunctionalExpression");
  var name = f.name;
  f.name = null;
  var g = CssConvert(f);
  g = CvConvert(g);
  g = CsConvert(g);
  g = CfConvert(g);
  g = CzConvert(g);
  return new CallExpression(
      new FunctionExpression(null, [], list(
          new VarStatement([], [{id:var_self, exp:f}]),
          name ? new VarStatement([], [{id:name, exp:var_self}]) : new EmptyStatement([]),
          new ExpStatement([], new SimpleAssignExpression(new DotAccessor(var_self, var_compiled), g)),
          new ReturnStatement([], var_self)
      )),
      []
  );
  /* Constructs the following structure:
      "(function(){",
      "  var $Concurrent_Thread_self = ", f, ";",
      name  ?  "var " + name + " = " + "$Concurrent_Thread_self;"  :  "",
      "  $Concurrent_Thread_self.$Concurrent_Thread_compiled = ", func, ";",
      "  return $Concurrent_Thread_self;",
      "})()"
  */
}


          return {
              compile: compile, prepareTree: prepareTree, prepare: prepare
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.compile = compile;
  this.Concurrent.Thread.prepareTree = prepareTree;
  this.Concurrent.Thread.prepare = prepare;
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Compiler || (typeof this.Concurrent.Thread.Compiler != 'object' && typeof this.Concurrent.Thread.Compiler != 'function') ) this.Concurrent.Thread.Compiler = new Object();
with ( function(){
with ( Concurrent.Thread.Compiler ) {

      return function () {
          var VERSION ;
          var NAMESPACE;
          



NAMESPACE = 'Concurrent.Thread.Compiler';



WebBrowser.ScriptExecuter.register("text/x-script.multithreaded-js", function ( src ){
  eval(compile(src)).async(null);
});

function compile ( src ) {
  var prog = (new Parser).parse(src);
  prog = new FunctionExpression(null, [], prog);
  prog = CssConvert(prog);
  prog = CvConvert(prog);
  prog = CsConvert(prog);
  prog = CfConvert(prog);
  prog.vars.forEach(function( it ){
      // Incredibly, window does not have hasOwnProperty method on IE!!
      if ( !Object.prototype.hasOwnProperty.call(window, it) ) window[it] = undefined;
  });
  prog.vars = [];
  prog = CzConvert(prog);
  return [
      "1, function(){",
      "    var $Concurrent_Thread_self = function(){};",
      "    $Concurrent_Thread_self.$Concurrent_Thread_compiled = ", prog, ";",
      "    return $Concurrent_Thread_self;",
      "}()"
  ].join("");
}

          return {
              
          };
      }();
  }
}.call(null) ) {
}
}).call(null);
(function(){
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Continuation || (typeof this.Concurrent.Thread.Continuation != 'object' && typeof this.Concurrent.Thread.Continuation != 'function') ) this.Concurrent.Thread.Continuation = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( this.Concurrent.Thread.Generator === undefined ) this.Concurrent.Thread.Generator = undefined;
with ( function(){
with ( Concurrent.Thread.Continuation ) {
with ( Concurrent ) {
with ( Concurrent.Thread ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Concurrent.Thread.Generator module.
*
* The Initial Developer of the Original Code is
* Daisuke Maki.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */



NAMESPACE = 'Concurrent.Thread';











function Generator ( f ) {
  if ( typeof f != "function" ) throw new TypeError("not a function");
  if ( typeof f.$Concurrent_Thread_compiled != "function" ) f = Thread.compile(f);
  this._mutex       = new Mutex();
  this._cont_caller = null;
  this._buf         = null;
  this._got         = false;
  
  var self = this;
  
  var generate = eval(Thread.prepare(function( x ){
      self._buf = x;
      self._got = true;
      try {
          self._cont_iter = currentContinuation();
          self._cont_caller();
      } catch ( e ) {
          self._cont_iter = null;
          if ( e instanceof ContinuationCalledException ) {
              return;  // resume iteration
          } else {
              throw e;
          }
      }
      // execution never reaches here
  }));
  
  this._cont_iter = eval(Thread.prepare(function(){
      f(generate);
      self._got       = false;
      self._cont_iter = null;  // null means that the iteration function has finished
      self._cont_caller();
  }));
}


var proto = Generator.prototype;


proto.hasNext = function ( ) {
  // This definition is called when generator is used in non-converted context.
  // The implementation is quite tricky and strongly dependent on the internal
  // implementation of Concurrent.Thread.

  if ( !this._mutex.isAcquirable() ) this._mutex.acquire();  // must throw an error
  if ( this._got            ) return true;
  if ( !this._cont_iter     ) return false;
  
  var is_called = false;
  this._cont_caller = eval(Thread.prepare(function(){
      is_called = true;
      Thread.stop();
  }));

  var triplet = Thread.create(this._cont_iter)._triplet;
  triplet.timeout = void 0;
  while ( 1 ) {
      while ( triplet.timeout === void 0 ) {
          try {
              triplet = triplet.continuation.procedure.call(
                            triplet.continuation.this_val, triplet.ret_val
                       );
          } catch ( e ) {
              if ( e instanceof NoContinuationException ) {
                  return this._got;
              } else if ( e instanceof NoExceptionHandlerException ) {
                  throw e.thrown;
              } else {
                  triplet.continuation = triplet.continuation.exception;
                  triplet.ret_val      = e;
              }
          }
      }
      if ( is_called ) {
          break;
      } else {
          triplet.continuation = triplet.continuation.exception;
          triplet.ret_val      = new Error("can't suspend in non-converted context");
      }
  }
  this._cont_caller = null;
  return this._got;
};


proto.hasNext.$Concurrent_Thread_compiled = eval(Thread.prepare(
  function ( ) {
      this._mutex.acquire();
      try {
          if ( this._got        ) return true;
          if ( !this._cont_iter ) return false;
          try {
              this._cont_caller = currentContinuation();
              this._cont_iter();
          } catch ( e ) {
              this._cont_caller = null;
              if ( e instanceof ContinuationCalledException ) {
                  return this._got;
              } else {
                  throw e;
              }
          }
      } finally {
          this._mutex.release();
      }
      // execution never reaches here
  }
)).$Concurrent_Thread_compiled;


proto.next = eval(Thread.prepare(
  function ( ) {
      if ( this.hasNext() ) {
          var x = this._buf;
          this._buf = void 0;
          this._got = false;
          return x;
      } else {
          return void 0;
      }
  }
));

          return {
              Generator: Generator
          };
      }();
  }
}
}
}.call(null) ) {
  this.Concurrent.Thread.Generator = Generator;
}
}).call(null);
(function(){
  if ( !this.Data || (typeof this.Data != 'object' && typeof this.Data != 'function') ) this.Data = new Object();
  if ( !this.Data.Error || (typeof this.Data.Error != 'object' && typeof this.Data.Error != 'function') ) this.Data.Error = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.JSON || (typeof this.Concurrent.Thread.JSON != 'object' && typeof this.Concurrent.Thread.JSON != 'function') ) this.Concurrent.Thread.JSON = new Object();
  if ( !this.Concurrent.Thread.JSON.RPC || (typeof this.Concurrent.Thread.JSON.RPC != 'object' && typeof this.Concurrent.Thread.JSON.RPC != 'function') ) this.Concurrent.Thread.JSON.RPC = new Object();
  if ( !this.JSON || (typeof this.JSON != 'object' && typeof this.JSON != 'function') ) this.JSON = new Object();
  if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
  if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
  if ( this.Concurrent.Thread.JSON.RPC.bind === undefined ) this.Concurrent.Thread.JSON.RPC.bind = undefined;
  if ( this.Concurrent.Thread.JSON.RPC.JSONRPCError === undefined ) this.Concurrent.Thread.JSON.RPC.JSONRPCError = undefined;
with ( function(){
with ( Data.Error ) {
with ( Util.Arrayize ) {
with ( JSON ) {
with ( Concurrent ) {
with ( Concurrent.Thread.JSON.RPC ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          


NAMESPACE = 'Concurrent.Thread.JSON.RPC';

















function bind ( opts ) {
  if ( !(opts instanceof Object) ) throw new TypeError("argument for " + NAMESPACE + ".bind must be a hash.");
  var request = opts.request;
  if ( request != null ) {
      if ( !String(request).match(/^(?:GET|POST)$/i) ) throw new Error('"request" option must be "GET" or "POST".');
  } else {
      request = "POST";
  }
  var params = opts.params;
  if ( params != null ) {
      if ( !String(params).match(/^(?:Named|Positioned)$/i) ) throw new Error('"params" option must be "Named" or "Positioned".');
  } else {
      params = "Named";
  }
  var body;
  if ( request.match(/^POST$/i) ) {
      if ( params.match(/^Named$/i) ) {
          body = makeNamedPost(opts.url, opts.method);
      } else {
          body = makePositionedPost(opts.url, opts.method);
      }
  } else {
      if ( params.match(/^Named$/i) ) {
          body = makeNamedGet(opts.url, opts.method);
      } else {
          body = makePositionedGet(opts.url, opts.method);
      }
  }
  var with_pre;
  var pre = opts.preprocess;
  if ( pre != null ) {
      if ( typeof pre != "function" ) throw new TypeError('"preprocess" option must be function');
      with_pre = eval(Thread.prepare(function(){
          return body.apply(this, pre.apply(this, arguments));
      }));
  } else {
      with_pre = body;
  }
  var post = opts.postprocess;
  if ( post != null ) {
      if ( typeof post != "function" ) throw new TypeError('"preprocess" option must be function');
      return eval(Thread.prepare(function(){
          return post(with_pre.apply(this, arguments));
      }));
  } else {
      return with_pre;
  }
}


var COMMON_HEADERS = [
  'User-Agent'  , 'Concurrent.Thread.JSON.RPC',
  'Accept'      , 'application/json'
];

var POST_HEADERS = COMMON_HEADERS.concat(
  'Content-type', 'application/json'
);

function makeNamedPost( url, method ) {
  return eval(Thread.prepare(
      function ( /* variable arguments */ ) {
          var res = Thread.Http.post(url, dump({
              version: "1.1",
              method : method,
              params : args2params(arguments)
          }), POST_HEADERS);
          res = eval("(" + res.responseText + ")");
          if ( res.error ) throw new JSONRPCError(res.error);
          return res.result;
      }
  ));
};

function makePositionedPost ( url, method ) {
  return eval(Thread.prepare(
      function ( /* variable arguments */ ) {
          var res = Thread.Http.post(url, dump({
              version: "1.1",
              method : method,
              params : arrayize(arguments)
          }), POST_HEADERS);
          res = eval("(" + res.responseText + ")");
          if ( res.error ) throw new JSONRPCError(res.error);
          return res.result;
      }
  ));
};

function makeNamedGet ( url, method ) {
  url = url.replace(/\/+$/, "") + "/" + encodeURIComponent(method) + "?";
  return eval(Thread.prepare(
      function ( /* variable arguments */ ) {
          var res = Thread.Http.get(url + params2query(args2params(arguments)), COMMON_HEADERS);
          res = eval("(" + res.responseText + ")");
          if ( res.error ) throw new JSONRPCError(res.error);
          return res.result;
      }
  ));
};

function makePositionedGet ( url, method ) {
  url = url.replace(/\/+$/, "") + "/" + encodeURIComponent(method) + "?";
  return eval(Thread.prepare(
      function ( /* variable arguments */ ) {
          arguments[arguments.length] = {};
          arguments.length++;
          var res = Thread.Http.get(url + params2query(args2params(arguments)), COMMON_HEADERS);
          res = eval("(" + res.responseText + ")");
          if ( res.error ) throw new JSONRPCError(res.error);
          return res.result;
      }
  ));
};

function args2params ( args ) {
  var params = {};
  if ( args.length ) {
      var hash = args[args.length-1];
      if ( !(hash instanceof Object) ) throw new Error("the last argument must be a hash");
      for ( var i in hash ) {
          if ( hash.hasOwnProperty(i) ) params[i] = hash[i];
      }
      for ( var i=0;  i < args.length-1;  i++ ) {
          params[i] = args[i];
      }
  }
  return params;
}

function params2query ( params ) {
  var query = [];
  for ( var i in params ) {
      if ( !params.hasOwnProperty(i) ) continue;
      if ( params[i] instanceof Array ) {
          var arr = params[i];
          for ( var j=0;  j < arr.length;  j++ ) {
              query.push(encodeURIComponent(i) + "=" + encodeURIComponent(arr[j]));
          }
      } else {
          query.push(encodeURIComponent(i) + "=" + encodeURIComponent(params[i]));
      }
  }
  return query.join("&");
}



var JSONRPCError = Error.extend(
  function ( $super, e ) {
      if ( e instanceof Object ) {
          $super(e.message);
          for ( var i in e ) this[i] = e[i];
      } else {
          $super(e);
      }
  },
  {name: NAMESPACE + ".JSONRPCError"}
);

          return {
              JSONRPCError: JSONRPCError, bind: bind
          };
      }();
  }
}
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.JSON.RPC.JSONRPCError = JSONRPCError;
  this.Concurrent.Thread.JSON.RPC.bind = bind;
}
}).call(null);
(function(){
  if ( !this.WebBrowser || (typeof this.WebBrowser != 'object' && typeof this.WebBrowser != 'function') ) this.WebBrowser = new Object();
  if ( !this.WebBrowser.GUI || (typeof this.WebBrowser.GUI != 'object' && typeof this.WebBrowser.GUI != 'function') ) this.WebBrowser.GUI = new Object();
  if ( !this.WebBrowser.GUI.Event || (typeof this.WebBrowser.GUI.Event != 'object' && typeof this.WebBrowser.GUI.Event != 'function') ) this.WebBrowser.GUI.Event = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent || (typeof this.Concurrent != 'object' && typeof this.Concurrent != 'function') ) this.Concurrent = new Object();
  if ( !this.Concurrent.Thread || (typeof this.Concurrent.Thread != 'object' && typeof this.Concurrent.Thread != 'function') ) this.Concurrent.Thread = new Object();
  if ( !this.Concurrent.Thread.Event || (typeof this.Concurrent.Thread.Event != 'object' && typeof this.Concurrent.Thread.Event != 'function') ) this.Concurrent.Thread.Event = new Object();
  if ( !this.Util || (typeof this.Util != 'object' && typeof this.Util != 'function') ) this.Util = new Object();
  if ( !this.Util.Arrayize || (typeof this.Util.Arrayize != 'object' && typeof this.Util.Arrayize != 'function') ) this.Util.Arrayize = new Object();
  if ( this.Concurrent.Thread.Event.waitFor === undefined ) this.Concurrent.Thread.Event.waitFor = undefined;
  if ( this.Concurrent.Thread.Event.select === undefined ) this.Concurrent.Thread.Event.select = undefined;
with ( function(){
with ( Util.Arrayize ) {
with ( WebBrowser.GUI.Event ) {
with ( Concurrent ) {
with ( Concurrent.Thread.Event ) {

      return function () {
          var VERSION = '0.0.0';
          var NAMESPACE;
          


NAMESPACE = 'Concurrent.Thread.Event';
















var waitFor = eval(Concurrent.Thread.prepare(
  function waitFor ( target, type, options ) {
      var arg = {};
      for ( var i in options ) arg[i] = options[i];
      arg.target = target;
      arg.type   = type;
      return select(arg);
  }
));



var select = eval(Concurrent.Thread.prepare(
  function select ( /* variable args */ ) {
      try {
          var signal = {};
          set_handlers(arrayize(arguments), signal);
          Concurrent.Thread.stop();
      } catch ( e ) {
          if ( e === signal ) {
              return signal.event;
          } else {
              throw e;
          }
      }
  }
));


function set_handlers ( args, signal ) {
  var self = Concurrent.Thread.self();
  
  args = args.map(function( arg ){
      if ( !arg.target || typeof arg.target !== "object" ) {
          throw new TypeError("not a object: " + target);
      }
      return {
          target         : arg.target,
          type           : String(arg.type),
          useCapture     : Boolean(arg.useCapture),
          preventDefault : Boolean(arg.preventDefault),
          stopPropagation: Boolean(arg.stopPropagation)
      };
  });
  
  var lsn_ids = args.map(function( arg ){
      function handler ( e ) {
          if ( arg.preventDefault  ) e.preventDefault();
          if ( arg.stopPropagation ) e.stopPropagation();
          lsn_ids.forEach(function( id ){
              detach(id);
          });
          // IE invalidates event properties after leaving the event handler.
          // So, we pass a copy of the current event object (but DO NOT copy its methods).
          var evt = {};
          for ( var i in e ) {
              if ( typeof e[i] !== "function" ) evt[i] = e[i];
          }
          signal.event  = evt;
          self.notify(signal);
      }
      return attach(arg.target, arg.type, handler, arg.useCapture);
  });
}

          return {
              waitFor: waitFor, select: select
          };
      }();
  }
}
}
}
}.call(null) ) {
  this.Concurrent.Thread.Event.waitFor = waitFor;
  this.Concurrent.Thread.Event.select = select;
}
}).call(null)